[Date Prev][Date Next] [Thread Prev][Thread Next]
[Thread Index]
[Date Index]
[Author Index]
rpms/kernel-xen-2.6/devel .gitignore, NONE, 1.1.2.1 gen-patches, NONE, 1.1.2.1 linux-2.6-0001-xen-debug-Add-xprintk-to-log-directly-via-hypercall.patch, NONE, 1.1.2.1 linux-2.6-0002-xen-dom0-Make-hvc_xen-console-work-for-dom0.patch, NONE, 1.1.2.1 linux-2.6-0003-xen-dom0-Initialize-xenbus-for-dom0.patch, NONE, 1.1.2.1 linux-2.6-0004-xen-dom0-Set-up-basic-IO-permissions-for-dom0.patch, NONE, 1.1.2.1 linux-2.6-0005-xen-dom0-Add-set_fixmap-pv_mmu_ops.patch, NONE, 1.1.2.1 linux-2.6-0006-xen-dom0-Add-support-for-the-platform_ops-hypercall.patch, NONE, 1.1.2.1 linux-2.6-0007-xen-acpi-Enable-early-access-to-ACPI-tables.patch, NONE, 1.1.2.1 linux-2.6-0008-xen-dom0-Add-paravirt_ops-ioremap_page_range-for.patch, NONE, 1.1.2.1 linux-2.6-0009-MTRR-use-cpu_callout_map-instead-of-cpu_online_map.patch, NONE, 1.1.2.1 linux-2.6-0010-xen-mtrr-Add-mtrr_ops-support-for-Xen-mtrr.patch, NONE, 1.1.2.1 linux-2.6-0011-xen-mtrr-Don-t-enable-xen-mtrr-on-bare-metal.patch, NONE, 1.1.2.1 linux-2.6-0012-xen-mtrr-set-cpu-in-cpu_callout_map.patch, NONE, 1.1.2.1 linux-2.6-0013-xen-mtrr-Clean-up-the-num_var_ranges-CPU_UNKOWN-hac.patch, NONE, 1.1.2.1 linux-2.6-0014-xen-mtrr-Use-specific-cpu_has_foo-macros-instead-of.patch, NONE, 1.1.2.1 linux-2.6-0015-xen-mtrr-Kill-some-unneccessary-includes.patch, NONE, 1.1.2.1 linux-2.6-0016-xen-mtrr-No-need-to-explicitly-set-use_intel_if-0.patch, NONE, 1.1.2.1 linux-2.6-0017-xen-mtrr-Use-generic_validate_add_page.patch, NONE, 1.1.2.1 linux-2.6-0018-xen-mtrr-Implement-xen_get_free_region.patch, NONE, 1.1.2.1 linux-2.6-0019-xen-mtrr-Add-xen_-get-set-_mtrr-implementations.patch, NONE, 1.1.2.1 linux-2.6-0020-irq2.diff-from-Juan-Quintela.patch, NONE, 1.1.2.1 linux-2.6-0021-xen-dom0-Obvious-cpuid-fix-to-domU-handling.patch, NONE, 1.1.2.1 linux-2.6-0022-xen-debug-Diagnose-bind_virq_to_irq-errors.patch, NONE, 1.1.2.1 linux-2.6-0023-xen-traps-Revert-Juan-s-traps_32.c-changes-to-debug.patch, NONE, 1.1.2.1 linux-2.6-0024-xen-debug-Move-init_apic_mappings-after-trap-init.patch, NONE, 1.1.2.1 linux-2.6-0025-xen-debug-Trace-progress-in-trap_init-around-init.patch, NONE, 1.1.2.1 linux-2.6-0026-xen-apic-Disable-init_apic_mappings-when-under-CO.patch, NONE, 1.1.2.1 linux-2.6-0027-xen-debug-Log-entry-into-virtual-console-s-xen_init.patch, NONE, 1.1.2.1 linux-2.6-0028-xen-debug-Log-bind_virq_to_irq-events.patch, NONE, 1.1.2.1 linux-2.6-0029-xen-debug-Work-around-USB-issue-triggered-by-Xen-de.patch, NONE, 1.1.2.1 linux-2.6-0030-Remove-duplicated-dma_alloc-free_noncoherent-define.patch, NONE, 1.1.2.1 linux-2.6-0031-xem-dom0-Add-hypervisor-memory_exchange-descriptor.patch, NONE, 1.1.2.1 linux-2.6-0032-xen-dom0-add-virt_to_pfn-macro.patch, NONE, 1.1.2.1 linux-2.6-0033-xen-dom0-use-virt_to_pfn-where-appropriate.patch, NONE, 1.1.2.1 linux-2.6-0034-xen-dom0-Add-contiguous-region-support.patch, NONE, 1.1.2.1 linux-2.6-0035-xen-dom0-Don-t-mask-off-PCD-bits-from-pte-entries.patch, NONE, 1.1.2.1 linux-2.6-0036-xen-dom0-Remove-duplicate-xen_store_interface-assig.patch, NONE, 1.1.2.1 linux-2.6-0037-xen-dom0-Slightly-re-arrange-xenbus_probe_init-er.patch, NONE, 1.1.2.1 linux-2.6-0038-xen-dom0-Use-max_low_pfn-declaration-from-linux-boo.patch, NONE, 1.1.2.1 linux-2.6-0039-xen-dma-Add-dma_mapping_ops-indirection-for-32-bit.patch, NONE, 1.1.2.1 linux-2.6-0040-xen-dma-Remove-unused-32-bit-dma_ops-map_simple-me.patch, NONE, 1.1.2.1 linux-2.6-0041-xen-dma-Initial-commit-of-pci-xen.c-dma-mapping-fun.patch, NONE, 1.1.2.1 linux-2.6-0042-xen-dma-Add-calls-to-dma_ops-alloc-free_coherent-ho.patch, NONE, 1.1.2.1 linux-2.6-0043-xen-dma-Add-xen_alloc-free_coherent.patch, NONE, 1.1.2.1 linux-2.6-0044-xen-dma-Don-t-merge-bios-on-xen-pvops.patch, NONE, 1.1.2.1 linux-2.6-0045-xen-dom0-Minor-coding-style-issue-in-ISA-mapping-co.patch, NONE, 1.1.2.1 linux-2.6-0046-xen-dom0-Use-i-PAGE_SHIFT-instead-of-PAGE_DOWN-i.patch, NONE, 1.1.2.1 linux-2.6-0047-xen-dom0-Match-up-set_pte_mfn-prototype-with-the.patch, NONE, 1.1.2.1 linux-2.6-0048-xen-dom0-Reserve-ISA-address-space-earlier.patch, NONE, 1.1.2.1 linux-2.6-0049-xen-Add-empty-xenctrl-module.patch, NONE, 1.1.2.1 linux-2.6-0050-xen-dom0-Add-proc-xen-capabilities.patch, NONE, 1.1.2.1 linux-2.6-0051-xen-Add-proc-xen-privcmd.patch, NONE, 1.1.2.1 linux-2.6-0052-xen-dom0-Add-proc-xen-xsd_-port-kva.patch, NONE, 1.1.2.1 linux-2.6-0053-xen-Add-proc-xen-xenbus.patch, NONE, 1.1.2.1 linux-2.6-0054-xen-Add-dev-xen-evtchn.patch, NONE, 1.1.2.1 linux-2.6-0055-xen-Add-__init-__exit-notations-to-xenctrl-function.patch, NONE, 1.1.2.1 linux-2.6-0056-xen-Add-Xen-s-sys-hypervisor-interface.patch, NONE, 1.1.2.1 linux-2.6-0057-xen-dom0-Add-basic-proc-xen-balloon.patch, NONE, 1.1.2.1 linux-2.6-0058-xen-dom0-Re-work-privcmd_ioctl-a-little.patch, NONE, 1.1.2.1 linux-2.6-0059-xen-dom0-Add-IOCTL_PRIVCMD_MMAP.patch, NONE, 1.1.2.1 linux-2.6-acpi-eeepc-hotkey.patch, NONE, 1.1.2.1 linux-2.6-agp-mm.patch, NONE, 1.1.2.1 linux-2.6-alsa-rc4-mm1.patch, NONE, 1.1.2.1 linux-2.6-alsa-support-sis7019.patch, NONE, 1.1.2.1 linux-2.6-at76.patch, NONE, 1.1.2.1 linux-2.6-ath5k-use-soft-wep.patch, NONE, 1.1.2.1 linux-2.6-compile-fix-gcc-43.patch, NONE, 1.1.2.1 linux-2.6-compile-fixes.patch, NONE, 1.3.2.1 linux-2.6-dcdbas-autoload.patch, NONE, 1.1.2.1 linux-2.6-debug-acpi-os-write-port.patch, NONE, 1.1.2.1 linux-2.6-default-mmf_dump_elf_headers.patch, NONE, 1.1.2.1 linux-2.6-drm-add-i915-radeon-mdt.patch, NONE, 1.1.2.1 linux-2.6-drm-mm.patch, NONE, 1.1.2.1 linux-2.6-drm-radeon-update.patch, NONE, 1.1.2.1 linux-2.6-e1000-corrupt-eeprom-checksum.patch, NONE, 1.1.2.1 linux-2.6-epoll-lockdep-annotation.patch, NONE, 1.1.2.1 linux-2.6-ext4-linus-git.patch, NONE, 1.1.2.1 linux-2.6-ext4-stable-queue.patch, NONE, 1.1.2.1 linux-2.6-firewire-git-pending.patch, NONE, 1.1.2.1 linux-2.6-firewire-git-update.patch, NONE, 1.1.2.1 linux-2.6-gelic-fixups.patch, NONE, 1.1.2.1 linux-2.6-gelic-wireless-fix.patch, NONE, 1.1.2.1 linux-2.6-gelic-wireless-v2.patch, NONE, 1.1.2.1 linux-2.6-git-initial-r500-drm.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-lirc.patch, NONE, 1.1.2.1 linux-2.6-netdev-atl2.patch, NONE, 1.1.2.1 linux-2.6-netdev-bonding-fix-null-deref.patch, NONE, 1.1.2.1 linux-2.6-netdev-e1000-disable-alpm.patch, NONE, 1.1.2.1 linux-2.6-pasemi-for-2.6.25.patch, NONE, 1.1.2.1 linux-2.6-pasemi-reserve-i2c.patch, NONE, 1.1.2.1 linux-2.6-powerpc-bootwrapper.patch, NONE, 1.1.2.1 linux-2.6-powerpc-generic-suspend-001-pmu-no-lock-kernel.patch, NONE, 1.1.2.1 linux-2.6-powerpc-generic-suspend-002-pmu-remove-dead-code.patch, NONE, 1.1.2.1 linux-2.6-powerpc-generic-suspend-003-remove-adb-sleep-notifier.patch, NONE, 1.1.2.1 linux-2.6-powerpc-generic-suspend-004-kill-pmu-sleep-notifier.patch, NONE, 1.1.2.1 linux-2.6-powerpc-generic-suspend-005-proper-sleep-management.patch, NONE, 1.1.2.1 linux-2.6-ppc-rtc.patch, NONE, 1.1.2.1 linux-2.6-ps3-legacy-bootloader-hack.patch, NONE, 1.1.2.1 linux-2.6-ps3-storage-alias.patch, NONE, 1.1.2.1 linux-2.6-rndis_wlan.patch, NONE, 1.1.2.1 linux-2.6-scsi-mpt-vmware-fix.patch, NONE, 1.1.2.1 linux-2.6-selinux-strip-leading-slashes.patch, NONE, 1.1.2.1 linux-2.6-smarter-relatime.patch, NONE, 1.1.2.1 linux-2.6-usb-ehci-hcd-respect-nousb.patch, NONE, 1.1.2.1 linux-2.6-utrace-ptrace-compat-avr32.patch, NONE, 1.1.2.1 linux-2.6-utrace-regset-avr32.patch, NONE, 1.1.2.1 linux-2.6-utrace-tracehook-avr32.patch, NONE, 1.1.2.1 linux-2.6-uvcvideo.patch, NONE, 1.1.2.1 linux-2.6-wireless-pending.patch, NONE, 1.1.2.1 linux-2.6-x86-debug-boot.patch, NONE, 1.1.2.1 linux-2.6-xfs-optimize-away-realtime-tests.patch, NONE, 1.1.2.1 linux-2.6-xfs-setfattr-32bit-compat.patch, NONE, 1.1.2.1 linux-2.6-xfs-xfs_mount-refactor.patch, NONE, 1.1.2.1 linux-2.6.24.tar.bz2.sign, NONE, 1.1.2.1 mirrors, NONE, 1.1.2.1 upstream, NONE, 1.1.2.1 upstream-key.gpg, NONE, 1.1.2.1 .cvsignore, 1.11, 1.11.2.1 Makefile, 1.2, 1.2.6.1 Makefile.config, 1.2, 1.2.4.1 config-debug, 1.2, 1.2.4.1 config-generic, 1.2, 1.2.4.1 config-ia64-generic, 1.2, 1.2.4.1 config-nodebug, 1.2, 1.2.4.1 config-powerpc-generic, 1.2, 1.2.4.1 config-powerpc32-generic, 1.2, 1.2.4.1 config-powerpc64, 1.2, 1.2.4.1 config-s390x, 1.2, 1.2.4.1 config-sparc-generic, 1.2, 1.2.4.1 config-sparc64-generic, 1.2, 1.2.4.1 config-x86-generic, 1.2, 1.2.4.1 config-x86_64-generic, 1.2, 1.2.4.1 config-xen-generic, 1.2, 1.2.4.1 config-xen-ia64, 1.2, 1.2.4.1 config-xen-x86, 1.2, 1.2.4.1 config-xen-x86_64, 1.2, 1.2.4.1 kernel.spec, 1.11, 1.11.2.1 linux-2.6-ata-quirk.patch, 1.2, 1.2.8.1 linux-2.6-build-nonintconfig.patch, 1.1, 1.1.22.1 linux-2.6-crash-driver.patch, 1.2, 1.2.8.1 linux-2.6-debug-nmi-timeout.patch, 1.2, 1.2.8.1 linux-2.6-debug-spinlock-taint.patch, 1.1, 1.1.22.1 linux-2.6-debug-taint-vm.patch, 1.3, 1.3.8.1 linux-2.6-defaults-fat-utf8.patch, 1.1, 1.1.22.1 linux-2.6-devmem.patch, 1.3, 1.3.8.1 linux-2.6-execshield.patch, 1.3, 1.3.8.1 linux-2.6-input-kill-stupid-messages.patch, 1.1, 1.1.22.1 linux-2.6-net-silence-noisy-printks.patch, 1.2, 1.2.8.1 linux-2.6-ppc32-ucmpdi2.patch, 1.1, 1.1.22.1 linux-2.6-ps3-ehci-iso.patch, 1.2, 1.2.8.1 linux-2.6-selinux-mprotect-checks.patch, 1.1, 1.1.22.1 linux-2.6-serial-460800.patch, 1.1, 1.1.22.1 linux-2.6-silence-noise.patch, 1.3, 1.3.8.1 linux-2.6-squashfs.patch, 1.3, 1.3.8.1 linux-2.6-unexport-symbols.patch, 1.1, 1.1.22.1 linux-2.6-utrace-core.patch, 1.2, 1.2.8.1 linux-2.6-utrace-ptrace-compat-ia64.patch, 1.2, 1.2.8.1 linux-2.6-utrace-ptrace-compat-s390.patch, 1.2, 1.2.8.1 linux-2.6-utrace-ptrace-compat-sparc64.patch, 1.2, 1.2.8.1 linux-2.6-utrace-ptrace-compat.patch, 1.2, 1.2.8.1 linux-2.6-utrace-regset-ia64.patch, 1.2, 1.2.8.1 linux-2.6-utrace-regset-s390.patch, 1.2, 1.2.8.1 linux-2.6-utrace-regset-sparc64.patch, 1.2, 1.2.8.1 linux-2.6-utrace-regset.patch, 1.2, 1.2.8.1 linux-2.6-utrace-tracehook-ia64.patch, 1.2, 1.2.8.1 linux-2.6-utrace-tracehook-s390.patch, 1.2, 1.2.8.1 linux-2.6-utrace-tracehook-sparc64.patch, 1.2, 1.2.8.1 linux-2.6-utrace-tracehook-um.patch, 1.2, 1.2.8.1 linux-2.6-utrace-tracehook.patch, 1.2, 1.2.8.1 linux-2.6-wireless.patch, 1.2, 1.2.8.1 linux-2.6-x86-tune-generic.patch, 1.1, 1.1.22.1 nouveau-drm.patch, 1.2, 1.2.8.1 sources, 1.11, 1.11.2.1 xen-build-id.patch, 1.2, 1.2.4.1 xen-compile-fix.patch, 1.3, 1.3.8.1 xen-syms-build-id.patch, 1.2, 1.2.4.1 config-olpc-generic, 1.1, NONE git-wireless-dev.patch, 1.2, NONE kernel-2.6.21.7-i686-xen.config, 1.3, NONE kernel-2.6.21.7-x86_64-xen.config, 1.3, NONE linux-2.6-2110_scsi-sd-printing.patch, 1.2, NONE linux-2.6-2111_sd-start-stop.patch, 1.2, NONE linux-2.6-2112_libata-suspend.patch, 1.2, NONE linux-2.6-2113_libata-spindown-compat.patch, 1.2, NONE linux-2.6-2114_libata-shutdown-warning.patch, 1.2, NONE linux-2.6-2115_libata-spindown-status.patch, 1.2, NONE linux-2.6-2116_libata-remove-spindown-compat.patch, 1.2, NONE linux-2.6-2117_sata-via-suspend.patch, 1.2, NONE linux-2.6-2118_scsi-constants.patch, 1.2, NONE linux-2.6-3w-9xxx-mem_len.patch, 1.1, NONE linux-2.6-PT_LOAD-align.patch, 1.1, NONE linux-2.6-acpi-boot-regression.patch, 1.2, NONE linux-2.6-acpi-config_pm-poweroff.patch, 1.1, NONE linux-2.6-acpi-dock-oops.patch, 1.2, NONE linux-2.6-acpi-keep-tsc-stable-when-lapic-timer-c2-ok-is-set.patch, 1.2, NONE linux-2.6-acpi-preserve-ebx-in-acpi_copy_wakeup_routine.patch, 1.2, NONE linux-2.6-acpi-unblacklist-dell-gx240.patch, 1.2, NONE linux-2.6-amd-disabled-svm-detect-msr-1.patch, 1.2, NONE linux-2.6-amd-disabled-svm-detect.patch, 1.2, NONE linux-2.6-ata-call-check-dma-with-qc-prepared.patch, 1.2, NONE linux-2.6-ata-use-pio-for-non-16-byte-xfers.patch, 1.2, NONE linux-2.6-bcm43xx-pci-neuter.patch, 1.2, NONE linux-2.6-cell-spu-device-tree.patch, 1.2, NONE linux-2.6-cell-spufs-fixes.patch, 1.2, NONE linux-2.6-clockevents-fix-resume-logic.patch, 1.2, NONE linux-2.6-common-uevent.patch, 1.2, NONE linux-2.6-crap-sysfs-workaround.patch, 1.2, NONE linux-2.6-crash-driver-xen.patch, 1.2, NONE linux-2.6-cve-2008-0600.patch, 1.1, NONE linux-2.6-debug-boot-delay.patch, 1.2, NONE linux-2.6-debug-extra-warnings.patch, 1.2, NONE linux-2.6-debug-must_check.patch, 1.1, NONE linux-2.6-debug-slab-backtrace.patch, 1.1, NONE linux-2.6-debug-sysfs-crash-debugging-xen.patch, 1.2, NONE linux-2.6-debug-sysfs-crash-debugging.patch, 1.2, NONE linux-2.6-defaults-nonmi.patch, 1.1, NONE linux-2.6-defaults-pci_no_msi_mmconf.patch, 1.2, NONE linux-2.6-defaults-unicode-vt.patch, 1.1, NONE linux-2.6-devmem-xen.patch, 1.2, NONE linux-2.6-disable-netback-checksum.patch, 1.3, NONE linux-2.6-dvb-spinlock.patch, 1.2, NONE linux-2.6-execshield-xen.patch, 1.2, NONE linux-2.6-firewire-be32-fix.patch, 1.2, NONE linux-2.6-firewire.patch, 1.2, NONE linux-2.6-fix-pmops-1.patch, 1.2, NONE linux-2.6-fix-pmops-2.patch, 1.2, NONE linux-2.6-fix-pmops-3.patch, 1.2, NONE linux-2.6-fix-pmops-4.patch, 1.2, NONE linux-2.6-gfs2-update.patch, 1.2, NONE linux-2.6-i82875-edac-pci-setup.patch, 1.2, NONE linux-2.6-i965gm-support.patch, 1.2, NONE linux-2.6-ibmvscsi-schizo.patch, 1.1, NONE linux-2.6-kvm-19.patch, 1.2, NONE linux-2.6-kvm-reinit-real-mode-tss.patch, 1.2, NONE linux-2.6-libata-atiixp-ids.patch, 1.2, NONE linux-2.6-libata-hpa.patch, 1.2, NONE linux-2.6-libata-ich8m-add-pciid.patch, 1.2, NONE linux-2.6-libata-ncq-blacklist-2.6.22-rc7.patch, 1.2, NONE linux-2.6-libata-pata-hpt3x2n-correct-revision-boundary.patch, 1.2, NONE linux-2.6-libata-pata-pcmcia-new-ident.patch, 1.2, NONE linux-2.6-libata-pata-sis-fix-timing.patch, 1.2, NONE linux-2.6-libata-pata_dma-param.patch, 1.2, NONE linux-2.6-libata-pata_it821x-partly-fix-dma.patch, 1.2, NONE linux-2.6-libata-sata_nv-adma.patch, 1.2, NONE linux-2.6-libata-sata_nv-wildcard-removal.patch, 1.2, NONE linux-2.6-libata-setxfer.patch, 1.2, NONE linux-2.6-libata_ali_max_dma_speed.patch, 1.2, NONE linux-2.6-libertas.diff, 1.2, NONE linux-2.6-mm-udf-fixes.patch, 1.2, NONE linux-2.6-modsign-core.patch, 1.3, NONE linux-2.6-modsign-crypto.patch, 1.3, NONE linux-2.6-modsign-include.patch, 1.3, NONE linux-2.6-modsign-ksign.patch, 1.3, NONE linux-2.6-modsign-mpilib.patch, 1.3, NONE linux-2.6-modsign-script.patch, 1.3, NONE linux-2.6-modsign-verify.patch, 1.1, NONE linux-2.6-module_version.patch, 1.2, NONE linux-2.6-mpc52xx-fec.patch, 1.2, NONE linux-2.6-mpc52xx-sdma.patch, 1.2, NONE linux-2.6-net-e1000-no-msi-warning.patch, 1.2, NONE linux-2.6-netdev-e1000e-01.patch, 1.1, NONE linux-2.6-netdev-e1000e-02.patch, 1.1, NONE linux-2.6-netdev-e1000e-03.patch, 1.1, NONE linux-2.6-netdev-e1000e-04.patch, 1.1, NONE linux-2.6-netdev-e1000e-05.patch, 1.1, NONE linux-2.6-netdev-e1000e-06.patch, 1.1, NONE linux-2.6-netdev-e1000e-07.patch, 1.1, NONE linux-2.6-netdev-e1000e-08.patch, 1.1, NONE linux-2.6-netdev-e1000e-09.patch, 1.1, NONE linux-2.6-netdev-e1000e-10.patch, 1.1, NONE linux-2.6-netdev-e1000e-backport.patch, 1.1, NONE linux-2.6-nfs-missing-braces.patch, 1.2, NONE linux-2.6-nfs-noreaddirplus.patch, 1.2, NONE linux-2.6-olpc-touchpad.diff, 1.2, NONE linux-2.6-ondemand-timer.patch, 1.2, NONE linux-2.6-oprofile-0.9.3.patch, 1.1, NONE linux-2.6-optimise-spinlock-debug.patch, 1.1, NONE linux-2.6-pmac-zilog.patch, 1.2, NONE linux-2.6-powermac-generic-suspend-1.patch, 1.2, NONE linux-2.6-powermac-generic-suspend-2.patch, 1.2, NONE linux-2.6-powermac-generic-suspend-3.patch, 1.2, NONE linux-2.6-powermac-generic-suspend-4.patch, 1.2, NONE linux-2.6-powerpc-reserve-initrd-1.patch, 1.2, NONE linux-2.6-powerpc-reserve-initrd-2.patch, 1.2, NONE linux-2.6-powerpc-slabalign.patch, 1.2, NONE linux-2.6-ppc-data-exception.patch, 1.2, NONE linux-2.6-proc-self-maps-fix.patch, 1.2, NONE linux-2.6-ps3-clear-spu-irq.patch, 1.2, NONE linux-2.6-ps3-device-init.patch, 1.2, NONE linux-2.6-ps3-ethernet-autoload.patch, 1.2, NONE linux-2.6-ps3-ethernet-modular.patch, 1.2, NONE linux-2.6-ps3-gelic-wireless.patch, 1.2, NONE linux-2.6-ps3-gelic.patch, 1.2, NONE linux-2.6-ps3-kexec.patch, 1.2, NONE linux-2.6-ps3-legacy-ioport.patch, 1.2, NONE linux-2.6-ps3-memory-probe.patch, 1.2, NONE linux-2.6-ps3-smp-boot.patch, 1.2, NONE linux-2.6-ps3-sound-autoload.patch, 1.2, NONE linux-2.6-ps3-sound.patch, 1.2, NONE linux-2.6-ps3-stable-patches.patch, 1.2, NONE linux-2.6-ps3-storage.patch, 1.2, NONE linux-2.6-ps3-system-bus-rework-2.patch, 1.2, NONE linux-2.6-ps3-system-bus-rework.patch, 1.2, NONE linux-2.6-ps3-usb-autoload.patch, 1.2, NONE linux-2.6-ps3-wrap-spu-runctl.patch, 1.2, NONE linux-2.6-ps3av-export-header.patch, 1.2, NONE linux-2.6-ps3fb-panic.patch, 1.2, NONE linux-2.6-raid-autorun.patch, 1.1, NONE linux-2.6-scsi-bounce-isa.patch, 1.2, NONE linux-2.6-sha_alignment.patch, 1.1, NONE linux-2.6-softirq-printout-irq-trace-events.patch, 1.2, NONE linux-2.6-softlockup-disable.patch, 1.2, NONE linux-2.6-sumversion-limits-dot-h.patch, 1.1, NONE linux-2.6-suspend-ordering.patch, 1.2, NONE linux-2.6-sysfs-inode-allocator-oops.patch, 1.2, NONE linux-2.6-udf-2.6.22-rc2-1-udf_data_corruption.patch, 1.2, NONE linux-2.6-udf-2.6.22-rc4-1-udf_block_leak.patch, 1.2, NONE linux-2.6-uevent-ebus.patch, 1.1, NONE linux-2.6-uevent-macio.patch, 1.1, NONE linux-2.6-uevent-of_platform.patch, 1.1, NONE linux-2.6-usb-autosuspend-default-disable.patch, 1.2, NONE linux-2.6-use-build-id-ld-option.patch, 1.2, NONE linux-2.6-utrace-ptrace-compat-xen.patch, 1.2, NONE linux-2.6-utrace-recalc_sigpending_and_wake.patch, 1.2, NONE linux-2.6-utrace-sig_kernel-macros.patch, 1.2, NONE linux-2.6-utrace-tracehook-xen.patch, 1.2, NONE linux-2.6-vm-invalidate_mapping_pages-cond-resched.patch, 1.2, NONE linux-2.6-vm-silence-atomic-alloc-failures.patch, 1.1, NONE linux-2.6-wakeups-hdaps.patch, 1.2, NONE linux-2.6-x86-64-edac-support.patch, 1.1, NONE linux-2.6-x86-64_pmtrace.patch, 1.2, NONE linux-2.6-x86-dell-hpet.patch, 1.2, NONE linux-2.6-x86-dont-delete-cpu_devs-data.patch, 1.2, NONE linux-2.6-x86-fsc-interrupt-controller-quirk.patch, 1.2, NONE linux-2.6-x86-vga-vidfail.patch, 1.1, NONE linux-2.6-x86_64-silence-up-apic-errors-xen.patch, 1.2, NONE linux-2.6-x86_64-silence-up-apic-errors.patch, 1.1, NONE linux-2.6-xen-backwards-time.patch, 1.1, NONE linux-2.6-xen-blkfront-wait-add.patch, 1.3, NONE linux-2.6-xen-fix-irq-warn-mismerge.patch, 1.1, NONE linux-2.6-xen-irq_vector-uninitialize.patch, 1.1, NONE linux-2.6-xen-paravirt-nographics-pvfb-fix.patch, 1.2, NONE linux-2.6-xen-privcmd-use-nopfn.patch, 1.1, NONE linux-2.6-xen-sleazy-fpu-i386.patch, 1.1, NONE linux-2.6-xen-sleazy-fpu-x86_64.patch, 1.1, NONE linux-2.6.20.tar.bz2.sign, 1.1, NONE
- From: Mark McLoughlin (markmc) <fedora-extras-commits redhat com>
- To: fedora-extras-commits redhat com
- Subject: rpms/kernel-xen-2.6/devel .gitignore, NONE, 1.1.2.1 gen-patches, NONE, 1.1.2.1 linux-2.6-0001-xen-debug-Add-xprintk-to-log-directly-via-hypercall.patch, NONE, 1.1.2.1 linux-2.6-0002-xen-dom0-Make-hvc_xen-console-work-for-dom0.patch, NONE, 1.1.2.1 linux-2.6-0003-xen-dom0-Initialize-xenbus-for-dom0.patch, NONE, 1.1.2.1 linux-2.6-0004-xen-dom0-Set-up-basic-IO-permissions-for-dom0.patch, NONE, 1.1.2.1 linux-2.6-0005-xen-dom0-Add-set_fixmap-pv_mmu_ops.patch, NONE, 1.1.2.1 linux-2.6-0006-xen-dom0-Add-support-for-the-platform_ops-hypercall.patch, NONE, 1.1.2.1 linux-2.6-0007-xen-acpi-Enable-early-access-to-ACPI-tables.patch, NONE, 1.1.2.1 linux-2.6-0008-xen-dom0-Add-paravirt_ops-ioremap_page_range-for.patch, NONE, 1.1.2.1 linux-2.6-0009-MTRR-use-cpu_callout_map-instead-of-cpu_online_map.patch, NONE, 1.1.2.1 linux-2.6-0010-xen-mtrr-Add-mtrr_ops-support-for-Xen-mtrr.patch, NONE, 1.1.2.1 linux-2.6-0011-xen-mtrr-Don-t-enable-xen-mtrr-on-bare-metal.patch, NONE, 1.1.2.1 linux-2.6-0012-xen-mtrr-set-cpu-in-cpu_callout_map.patch, NONE, 1.1.2.1 linux-2.6-0013-xen-mtrr-Clean-up-the-num_var_ranges-CPU_UNKOWN-hac.patch, NONE, 1.1.2.1 linux-2.6-0014-xen-mtrr-Use-specific-cpu_has_foo-macros-instead-of.patch, NONE, 1.1.2.1 linux-2.6-0015-xen-mtrr-Kill-some-unneccessary-includes.patch, NONE, 1.1.2.1 linux-2.6-0016-xen-mtrr-No-need-to-explicitly-set-use_intel_if-0.patch, NONE, 1.1.2.1 linux-2.6-0017-xen-mtrr-Use-generic_validate_add_page.patch, NONE, 1.1.2.1 linux-2.6-0018-xen-mtrr-Implement-xen_get_free_region.patch, NONE, 1.1.2.1 linux-2.6-0019-xen-mtrr-Add-xen_-get-set-_mtrr-implementations.patch, NONE, 1.1.2.1 linux-2.6-0020-irq2.diff-from-Juan-Quintela.patch, NONE, 1.1.2.1 linux-2.6-0021-xen-dom0-Obvious-cpuid-fix-to-domU-handling.patch, NONE, 1.1.2.1 linux-2.6-0022-xen-debug-Diagnose-bind_virq_to_irq-errors.patch, NONE, 1.1.2.1 linux-2.6-0023-xen-traps-Revert-Juan-s-traps_32.c-changes-to-debug.patch, NONE, 1.1.2.1 linux-2.6-0024-xen-debug-Move-init_apic_mappings-after-trap-init.patch, NONE, 1.1.2.1 linux-2.6-0025-xen-debug-Trace-progress-in-trap_init-around-init.patch, NONE, 1.1.2.1 linux-2.6-0026-xen-apic-Disable-init_apic_mappings-when-under-CO.patch, NONE, 1.1.2.1 linux-2.6-0027-xen-debug-Log-entry-into-virtual-console-s-xen_init.patch, NONE, 1.1.2.1 linux-2.6-0028-xen-debug-Log-bind_virq_to_irq-events.patch, NONE, 1.1.2.1 linux-2.6-0029-xen-debug-Work-around-USB-issue-triggered-by-Xen-de.patch, NONE, 1.1.2.1 linux-2.6-0030-Remove-duplicated-dma_alloc-free_noncoherent-define.patch, NONE, 1.1.2.1 linux-2.6-0031-xem-dom0-Add-hypervisor-memory_exchange-descriptor.patch, NONE, 1.1.2.1 linux-2.6-0032-xen-dom0-add-virt_to_pfn-macro.patch, NONE, 1.1.2.1 linux-2.6-0033-xen-dom0-use-virt_to_pfn-where-appropriate.patch, NONE, 1.1.2.1 linux-2.6-0034-xen-dom0-Add-contiguous-region-support.patch, NONE, 1.1.2.1 linux-2.6-0035-xen-dom0-Don-t-mask-off-PCD-bits-from-pte-entries.patch, NONE, 1.1.2.1 linux-2.6-0036-xen-dom0-Remove-duplicate-xen_store_interface-assig.patch, NONE, 1.1.2.1 linux-2.6-0037-xen-dom0-Slightly-re-arrange-xenbus_probe_init-er.patch, NONE, 1.1.2.1 linux-2.6-0038-xen-dom0-Use-max_low_pfn-declaration-from-linux-boo.patch, NONE, 1.1.2.1 linux-2.6-0039-xen-dma-Add-dma_mapping_ops-indirection-for-32-bit.patch, NONE, 1.1.2.1 linux-2.6-0040-xen-dma-Remove-unused-32-bit-dma_ops-map_simple-me.patch, NONE, 1.1.2.1 linux-2.6-0041-xen-dma-Initial-commit-of-pci-xen.c-dma-mapping-fun.patch, NONE, 1.1.2.1 linux-2.6-0042-xen-dma-Add-calls-to-dma_ops-alloc-free_coherent-ho.patch, NONE, 1.1.2.1 linux-2.6-0043-xen-dma-Add-xen_alloc-free_coherent.patch, NONE, 1.1.2.1 linux-2.6-0044-xen-dma-Don-t-merge-bios-on-xen-pvops.patch, NONE, 1.1.2.1 linux-2.6-0045-xen-dom0-Minor-coding-style-issue-in-ISA-mapping-co.patch, NONE, 1.1.2.1 linux-2.6-0046-xen-dom0-Use-i-PAGE_SHIFT-instead-of-PAGE_DOWN-i.patch, NONE, 1.1.2.1 linux-2.6-0047-xen-dom0-Match-up-set_pte_mfn-prototype-with-the.patch, NONE, 1.1.2.1 linux-2.6-0048-xen-dom0-Reserve-ISA-address-space-earlier.patch, NONE, 1.1.2.1 linux-2.6-0049-xen-Add-empty-xenctrl-module.patch, NONE, 1.1.2.1 linux-2.6-0050-xen-dom0-Add-proc-xen-capabilities.patch, NONE, 1.1.2.1 linux-2.6-0051-xen-Add-proc-xen-privcmd.patch, NONE, 1.1.2.1 linux-2.6-0052-xen-dom0-Add-proc-xen-xsd_-port-kva.patch, NONE, 1.1.2.1 linux-2.6-0053-xen-Add-proc-xen-xenbus.patch, NONE, 1.1.2.1 linux-2.6-0054-xen-Add-dev-xen-evtchn.patch, NONE, 1.1.2.1 linux-2.6-0055-xen-Add-__init-__exit-notations-to-xenctrl-function.patch, NONE, 1.1.2.1 linux-2.6-0056-xen-Add-Xen-s-sys-hypervisor-interface.patch, NONE, 1.1.2.1 linux-2.6-0057-xen-dom0-Add-basic-proc-xen-balloon.patch, NONE, 1.1.2.1 linux-2.6-0058-xen-dom0-Re-work-privcmd_ioctl-a-little.patch, NONE, 1.1.2.1 linux-2.6-0059-xen-dom0-Add-IOCTL_PRIVCMD_MMAP.patch, NONE, 1.1.2.1 linux-2.6-acpi-eeepc-hotkey.patch, NONE, 1.1.2.1 linux-2.6-agp-mm.patch, NONE, 1.1.2.1 linux-2.6-alsa-rc4-mm1.patch, NONE, 1.1.2.1 linux-2.6-alsa-support-sis7019.patch, NONE, 1.1.2.1 linux-2.6-at76.patch, NONE, 1.1.2.1 linux-2.6-ath5k-use-soft-wep.patch, NONE, 1.1.2.1 linux-2.6-compile-fix-gcc-43.patch, NONE, 1.1.2.1 linux-2.6-compile-fixes.patch, NONE, 1.3.2.1 linux-2.6-dcdbas-autoload.patch, NONE, 1.1.2.1 linux-2.6-debug-acpi-os-write-port.patch, NONE, 1.1.2.1 linux-2.6-default-mmf_dump_elf_headers.patch, NONE, 1.1.2.1 linux-2.6-drm-add-i915-radeon-mdt.patch, NONE, 1.1.2.1 linux-2.6-drm-mm.patch, NONE, 1.1.2.1 linux-2.6-drm-radeon-update.patch, NONE, 1.1.2.1 linux-2.6-e1000-corrupt-eeprom-checksum.patch, NONE, 1.1.2.1 linux-2.6-epoll-lockdep-annotation.patch, NONE, 1.1.2.1 linux-2.6-ext4-linus-git.patch, NONE, 1.1.2.1 linux-2.6-ext4-stable-queue.patch, NONE, 1.1.2.1 linux-2.6-firewire-git-pending.patch, NONE, 1.1.2.1 linux-2.6-firewire-git-update.patch, NONE, 1.1.2.1 linux-2.6-gelic-fixups.patch, NONE, 1.1.2.1 linux-2.6-gelic-wireless-fix.patch, NONE, 1.1.2.1 linux-2.6-gelic-wireless-v2.patch, NONE, 1.1.2.1 linux-2.6-git-initial-r500-drm.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-lirc.patch, NONE, 1.1.2.1 linux-2.6-netdev-atl2.patch, NONE, 1.1.2.1 linux-2.6-netdev-bonding-fix-null-deref.patch, NONE, 1.1.2.1 linux-2.6-netdev-e1000-disable-alpm.patch, NONE, 1.1.2.1 linux-2.6-pasemi-for-2.6.25.patch, NONE, 1.1.2.1 linux-2.6-pasemi-reserve-i2c.patch, NONE, 1.1.2.1 linux-2.6-powerpc-bootwrapper.patch, NONE, 1.1.2.1 linux-2.6-powerpc-generic-suspend-001-pmu-no-lock-kernel.patch, NONE, 1.1.2.1 linux-2.6-powerpc-generic-suspend-002-pmu-remove-dead-code.patch, NONE, 1.1.2.1 linux-2.6-powerpc-generic-suspend-003-remove-adb-sleep-notifier.patch, NONE, 1.1.2.1 linux-2.6-powerpc-generic-suspend-004-kill-pmu-sleep-notifier.patch, NONE, 1.1.2.1 linux-2.6-powerpc-generic-suspend-005-proper-sleep-management.patch, NONE, 1.1.2.1 linux-2.6-ppc-rtc.patch, NONE, 1.1.2.1 linux-2.6-ps3-legacy-bootloader-hack.patch, NONE, 1.1.2.1 linux-2.6-ps3-storage-alias.patch, NONE, 1.1.2.1 linux-2.6-rndis_wlan.patch, NONE, 1.1.2.1 linux-2.6-scsi-mpt-vmware-fix.patch, NONE, 1.1.2.1 linux-2.6-selinux-strip-leading-slashes.patch, NONE, 1.1.2.1 linux-2.6-smarter-relatime.patch, NONE, 1.1.2.1 linux-2.6-usb-ehci-hcd-respect-nousb.patch, NONE, 1.1.2.1 linux-2.6-utrace-ptrace-compat-avr32.patch, NONE, 1.1.2.1 linux-2.6-utrace-regset-avr32.patch, NONE, 1.1.2.1 linux-2.6-utrace-tracehook-avr32.patch, NONE, 1.1.2.1 linux-2.6-uvcvideo.patch, NONE, 1.1.2.1 linux-2.6-wireless-pending.patch, NONE, 1.1.2.1 linux-2.6-x86-debug-boot.patch, NONE, 1.1.2.1 linux-2.6-xfs-optimize-away-realtime-tests.patch, NONE, 1.1.2.1 linux-2.6-xfs-setfattr-32bit-compat.patch, NONE, 1.1.2.1 linux-2.6-xfs-xfs_mount-refactor.patch, NONE, 1.1.2.1 linux-2.6.24.tar.bz2.sign, NONE, 1.1.2.1 mirrors, NONE, 1.1.2.1 upstream, NONE, 1.1.2.1 upstream-key.gpg, NONE, 1.1.2.1 .cvsignore, 1.11, 1.11.2.1 Makefile, 1.2, 1.2.6.1 Makefile.config, 1.2, 1.2.4.1 config-debug, 1.2, 1.2.4.1 config-generic, 1.2, 1.2.4.1 config-ia64-generic, 1.2, 1.2.4.1 config-nodebug, 1.2, 1.2.4.1 config-powerpc-generic, 1.2, 1.2.4.1 config-powerpc32-generic, 1.2, 1.2.4.1 config-powerpc64, 1.2, 1.2.4.1 config-s390x, 1.2, 1.2.4.1 config-sparc-generic, 1.2, 1.2.4.1 config-sparc64-generic, 1.2, 1.2.4.1 config-x86-generic, 1.2, 1.2.4.1 config-x86_64-generic, 1.2, 1.2.4.1 config-xen-generic, 1.2, 1.2.4.1 config-xen-ia64, 1.2, 1.2.4.1 config-xen-x86, 1.2, 1.2.4.1 config-xen-x86_64, 1.2, 1.2.4.1 kernel.spec, 1.11, 1.11.2.1 linux-2.6-ata-quirk.patch, 1.2, 1.2.8.1 linux-2.6-build-nonintconfig.patch, 1.1, 1.1.22.1 linux-2.6-crash-driver.patch, 1.2, 1.2.8.1 linux-2.6-debug-nmi-timeout.patch, 1.2, 1.2.8.1 linux-2.6-debug-spinlock-taint.patch, 1.1, 1.1.22.1 linux-2.6-debug-taint-vm.patch, 1.3, 1.3.8.1 linux-2.6-defaults-fat-utf8.patch, 1.1, 1.1.22.1 linux-2.6-devmem.patch, 1.3, 1.3.8.1 linux-2.6-execshield.patch, 1.3, 1.3.8.1 linux-2.6-input-kill-stupid-messages.patch, 1.1, 1.1.22.1 linux-2.6-net-silence-noisy-printks.patch, 1.2, 1.2.8.1 linux-2.6-ppc32-ucmpdi2.patch, 1.1, 1.1.22.1 linux-2.6-ps3-ehci-iso.patch, 1.2, 1.2.8.1 linux-2.6-selinux-mprotect-checks.patch, 1.1, 1.1.22.1 linux-2.6-serial-460800.patch, 1.1, 1.1.22.1 linux-2.6-silence-noise.patch, 1.3, 1.3.8.1 linux-2.6-squashfs.patch, 1.3, 1.3.8.1 linux-2.6-unexport-symbols.patch, 1.1, 1.1.22.1 linux-2.6-utrace-core.patch, 1.2, 1.2.8.1 linux-2.6-utrace-ptrace-compat-ia64.patch, 1.2, 1.2.8.1 linux-2.6-utrace-ptrace-compat-s390.patch, 1.2, 1.2.8.1 linux-2.6-utrace-ptrace-compat-sparc64.patch, 1.2, 1.2.8.1 linux-2.6-utrace-ptrace-compat.patch, 1.2, 1.2.8.1 linux-2.6-utrace-regset-ia64.patch, 1.2, 1.2.8.1 linux-2.6-utrace-regset-s390.patch, 1.2, 1.2.8.1 linux-2.6-utrace-regset-sparc64.patch, 1.2, 1.2.8.1 linux-2.6-utrace-regset.patch, 1.2, 1.2.8.1 linux-2.6-utrace-tracehook-ia64.patch, 1.2, 1.2.8.1 linux-2.6-utrace-tracehook-s390.patch, 1.2, 1.2.8.1 linux-2.6-utrace-tracehook-sparc64.patch, 1.2, 1.2.8.1 linux-2.6-utrace-tracehook-um.patch, 1.2, 1.2.8.1 linux-2.6-utrace-tracehook.patch, 1.2, 1.2.8.1 linux-2.6-wireless.patch, 1.2, 1.2.8.1 linux-2.6-x86-tune-generic.patch, 1.1, 1.1.22.1 nouveau-drm.patch, 1.2, 1.2.8.1 sources, 1.11, 1.11.2.1 xen-build-id.patch, 1.2, 1.2.4.1 xen-compile-fix.patch, 1.3, 1.3.8.1 xen-syms-build-id.patch, 1.2, 1.2.4.1 config-olpc-generic, 1.1, NONE git-wireless-dev.patch, 1.2, NONE kernel-2.6.21.7-i686-xen.config, 1.3, NONE kernel-2.6.21.7-x86_64-xen.config, 1.3, NONE linux-2.6-2110_scsi-sd-printing.patch, 1.2, NONE linux-2.6-2111_sd-start-stop.patch, 1.2, NONE linux-2.6-2112_libata-suspend.patch, 1.2, NONE linux-2.6-2113_libata-spindown-compat.patch, 1.2, NONE linux-2.6-2114_libata-shutdown-warning.patch, 1.2, NONE linux-2.6-2115_libata-spindown-status.patch, 1.2, NONE linux-2.6-2116_libata-remove-spindown-compat.patch, 1.2, NONE linux-2.6-2117_sata-via-suspend.patch, 1.2, NONE linux-2.6-2118_scsi-constants.patch, 1.2, NONE linux-2.6-3w-9xxx-mem_len.patch, 1.1, NONE linux-2.6-PT_LOAD-align.patch, 1.1, NONE linux-2.6-acpi-boot-regression.patch, 1.2, NONE linux-2.6-acpi-config_pm-poweroff.patch, 1.1, NONE linux-2.6-acpi-dock-oops.patch, 1.2, NONE linux-2.6-acpi-keep-tsc-stable-when-lapic-timer-c2-ok-is-set.patch, 1.2, NONE linux-2.6-acpi-preserve-ebx-in-acpi_copy_wakeup_routine.patch, 1.2, NONE linux-2.6-acpi-unblacklist-dell-gx240.patch, 1.2, NONE linux-2.6-amd-disabled-svm-detect-msr-1.patch, 1.2, NONE linux-2.6-amd-disabled-svm-detect.patch, 1.2, NONE linux-2.6-ata-call-check-dma-with-qc-prepared.patch, 1.2, NONE linux-2.6-ata-use-pio-for-non-16-byte-xfers.patch, 1.2, NONE linux-2.6-bcm43xx-pci-neuter.patch, 1.2, NONE linux-2.6-cell-spu-device-tree.patch, 1.2, NONE linux-2.6-cell-spufs-fixes.patch, 1.2, NONE linux-2.6-clockevents-fix-resume-logic.patch, 1.2, NONE linux-2.6-common-uevent.patch, 1.2, NONE linux-2.6-crap-sysfs-workaround.patch, 1.2, NONE linux-2.6-crash-driver-xen.patch, 1.2, NONE linux-2.6-cve-2008-0600.patch, 1.1, NONE linux-2.6-debug-boot-delay.patch, 1.2, NONE linux-2.6-debug-extra-warnings.patch, 1.2, NONE linux-2.6-debug-must_check.patch, 1.1, NONE linux-2.6-debug-slab-backtrace.patch, 1.1, NONE linux-2.6-debug-sysfs-crash-debugging-xen.patch, 1.2, NONE linux-2.6-debug-sysfs-crash-debugging.patch, 1.2, NONE linux-2.6-defaults-nonmi.patch, 1.1, NONE linux-2.6-defaults-pci_no_msi_mmconf.patch, 1.2, NONE linux-2.6-defaults-unicode-vt.patch, 1.1, NONE linux-2.6-devmem-xen.patch, 1.2, NONE linux-2.6-disable-netback-checksum.patch, 1.3, NONE linux-2.6-dvb-spinlock.patch, 1.2, NONE linux-2.6-execshield-xen.patch, 1.2, NONE linux-2.6-firewire-be32-fix.patch, 1.2, NONE linux-2.6-firewire.patch, 1.2, NONE linux-2.6-fix-pmops-1.patch, 1.2, NONE linux-2.6-fix-pmops-2.patch, 1.2, NONE linux-2.6-fix-pmops-3.patch, 1.2, NONE linux-2.6-fix-pmops-4.patch, 1.2, NONE linux-2.6-gfs2-update.patch, 1.2, NONE linux-2.6-i82875-edac-pci-setup.patch, 1.2, NONE linux-2.6-i965gm-support.patch, 1.2, NONE linux-2.6-ibmvscsi-schizo.patch, 1.1, NONE linux-2.6-kvm-19.patch, 1.2, NONE linux-2.6-kvm-reinit-real-mode-tss.patch, 1.2, NONE linux-2.6-libata-atiixp-ids.patch, 1.2, NONE linux-2.6-libata-hpa.patch, 1.2, NONE linux-2.6-libata-ich8m-add-pciid.patch, 1.2, NONE linux-2.6-libata-ncq-blacklist-2.6.22-rc7.patch, 1.2, NONE linux-2.6-libata-pata-hpt3x2n-correct-revision-boundary.patch, 1.2, NONE linux-2.6-libata-pata-pcmcia-new-ident.patch, 1.2, NONE linux-2.6-libata-pata-sis-fix-timing.patch, 1.2, NONE linux-2.6-libata-pata_dma-param.patch, 1.2, NONE linux-2.6-libata-pata_it821x-partly-fix-dma.patch, 1.2, NONE linux-2.6-libata-sata_nv-adma.patch, 1.2, NONE linux-2.6-libata-sata_nv-wildcard-removal.patch, 1.2, NONE linux-2.6-libata-setxfer.patch, 1.2, NONE linux-2.6-libata_ali_max_dma_speed.patch, 1.2, NONE linux-2.6-libertas.diff, 1.2, NONE linux-2.6-mm-udf-fixes.patch, 1.2, NONE linux-2.6-modsign-core.patch, 1.3, NONE linux-2.6-modsign-crypto.patch, 1.3, NONE linux-2.6-modsign-include.patch, 1.3, NONE linux-2.6-modsign-ksign.patch, 1.3, NONE linux-2.6-modsign-mpilib.patch, 1.3, NONE linux-2.6-modsign-script.patch, 1.3, NONE linux-2.6-modsign-verify.patch, 1.1, NONE linux-2.6-module_version.patch, 1.2, NONE linux-2.6-mpc52xx-fec.patch, 1.2, NONE linux-2.6-mpc52xx-sdma.patch, 1.2, NONE linux-2.6-net-e1000-no-msi-warning.patch, 1.2, NONE linux-2.6-netdev-e1000e-01.patch, 1.1, NONE linux-2.6-netdev-e1000e-02.patch, 1.1, NONE linux-2.6-netdev-e1000e-03.patch, 1.1, NONE linux-2.6-netdev-e1000e-04.patch, 1.1, NONE linux-2.6-netdev-e1000e-05.patch, 1.1, NONE linux-2.6-netdev-e1000e-06.patch, 1.1, NONE linux-2.6-netdev-e1000e-07.patch, 1.1, NONE linux-2.6-netdev-e1000e-08.patch, 1.1, NONE linux-2.6-netdev-e1000e-09.patch, 1.1, NONE linux-2.6-netdev-e1000e-10.patch, 1.1, NONE linux-2.6-netdev-e1000e-backport.patch, 1.1, NONE linux-2.6-nfs-missing-braces.patch, 1.2, NONE linux-2.6-nfs-noreaddirplus.patch, 1.2, NONE linux-2.6-olpc-touchpad.diff, 1.2, NONE linux-2.6-ondemand-timer.patch, 1.2, NONE linux-2.6-oprofile-0.9.3.patch, 1.1, NONE linux-2.6-optimise-spinlock-debug.patch, 1.1, NONE linux-2.6-pmac-zilog.patch, 1.2, NONE linux-2.6-powermac-generic-suspend-1.patch, 1.2, NONE linux-2.6-powermac-generic-suspend-2.patch, 1.2, NONE linux-2.6-powermac-generic-suspend-3.patch, 1.2, NONE linux-2.6-powermac-generic-suspend-4.patch, 1.2, NONE linux-2.6-powerpc-reserve-initrd-1.patch, 1.2, NONE linux-2.6-powerpc-reserve-initrd-2.patch, 1.2, NONE linux-2.6-powerpc-slabalign.patch, 1.2, NONE linux-2.6-ppc-data-exception.patch, 1.2, NONE linux-2.6-proc-self-maps-fix.patch, 1.2, NONE linux-2.6-ps3-clear-spu-irq.patch, 1.2, NONE linux-2.6-ps3-device-init.patch, 1.2, NONE linux-2.6-ps3-ethernet-autoload.patch, 1.2, NONE linux-2.6-ps3-ethernet-modular.patch, 1.2, NONE linux-2.6-ps3-gelic-wireless.patch, 1.2, NONE linux-2.6-ps3-gelic.patch, 1.2, NONE linux-2.6-ps3-kexec.patch, 1.2, NONE linux-2.6-ps3-legacy-ioport.patch, 1.2, NONE linux-2.6-ps3-memory-probe.patch, 1.2, NONE linux-2.6-ps3-smp-boot.patch, 1.2, NONE linux-2.6-ps3-sound-autoload.patch, 1.2, NONE linux-2.6-ps3-sound.patch, 1.2, NONE linux-2.6-ps3-stable-patches.patch, 1.2, NONE linux-2.6-ps3-storage.patch, 1.2, NONE linux-2.6-ps3-system-bus-rework-2.patch, 1.2, NONE linux-2.6-ps3-system-bus-rework.patch, 1.2, NONE linux-2.6-ps3-usb-autoload.patch, 1.2, NONE linux-2.6-ps3-wrap-spu-runctl.patch, 1.2, NONE linux-2.6-ps3av-export-header.patch, 1.2, NONE linux-2.6-ps3fb-panic.patch, 1.2, NONE linux-2.6-raid-autorun.patch, 1.1, NONE linux-2.6-scsi-bounce-isa.patch, 1.2, NONE linux-2.6-sha_alignment.patch, 1.1, NONE linux-2.6-softirq-printout-irq-trace-events.patch, 1.2, NONE linux-2.6-softlockup-disable.patch, 1.2, NONE linux-2.6-sumversion-limits-dot-h.patch, 1.1, NONE linux-2.6-suspend-ordering.patch, 1.2, NONE linux-2.6-sysfs-inode-allocator-oops.patch, 1.2, NONE linux-2.6-udf-2.6.22-rc2-1-udf_data_corruption.patch, 1.2, NONE linux-2.6-udf-2.6.22-rc4-1-udf_block_leak.patch, 1.2, NONE linux-2.6-uevent-ebus.patch, 1.1, NONE linux-2.6-uevent-macio.patch, 1.1, NONE linux-2.6-uevent-of_platform.patch, 1.1, NONE linux-2.6-usb-autosuspend-default-disable.patch, 1.2, NONE linux-2.6-use-build-id-ld-option.patch, 1.2, NONE linux-2.6-utrace-ptrace-compat-xen.patch, 1.2, NONE linux-2.6-utrace-recalc_sigpending_and_wake.patch, 1.2, NONE linux-2.6-utrace-sig_kernel-macros.patch, 1.2, NONE linux-2.6-utrace-tracehook-xen.patch, 1.2, NONE linux-2.6-vm-invalidate_mapping_pages-cond-resched.patch, 1.2, NONE linux-2.6-vm-silence-atomic-alloc-failures.patch, 1.1, NONE linux-2.6-wakeups-hdaps.patch, 1.2, NONE linux-2.6-x86-64-edac-support.patch, 1.1, NONE linux-2.6-x86-64_pmtrace.patch, 1.2, NONE linux-2.6-x86-dell-hpet.patch, 1.2, NONE linux-2.6-x86-dont-delete-cpu_devs-data.patch, 1.2, NONE linux-2.6-x86-fsc-interrupt-controller-quirk.patch, 1.2, NONE linux-2.6-x86-vga-vidfail.patch, 1.1, NONE linux-2.6-x86_64-silence-up-apic-errors-xen.patch, 1.2, NONE linux-2.6-x86_64-silence-up-apic-errors.patch, 1.1, NONE linux-2.6-xen-backwards-time.patch, 1.1, NONE linux-2.6-xen-blkfront-wait-add.patch, 1.3, NONE linux-2.6-xen-fix-irq-warn-mismerge.patch, 1.1, NONE linux-2.6-xen-irq_vector-uninitialize.patch, 1.1, NONE linux-2.6-xen-paravirt-nographics-pvfb-fix.patch, 1.2, NONE linux-2.6-xen-privcmd-use-nopfn.patch, 1.1, NONE linux-2.6-xen-sleazy-fpu-i386.patch, 1.1, NONE linux-2.6-xen-sleazy-fpu-x86_64.patch, 1.1, NONE linux-2.6.20.tar.bz2.sign, 1.1, NONE
- Date: Mon, 18 Feb 2008 11:56:24 -0500
Author: markmc
Update of /cvs/pkgs/rpms/kernel-xen-2.6/devel
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv31597
Modified Files:
Tag: private-markmc-pv-ops-branch
.cvsignore Makefile Makefile.config config-debug
config-generic config-ia64-generic config-nodebug
config-powerpc-generic config-powerpc32-generic
config-powerpc64 config-s390x config-sparc-generic
config-sparc64-generic config-x86-generic
config-x86_64-generic config-xen-generic config-xen-ia64
config-xen-x86 config-xen-x86_64 kernel.spec
linux-2.6-ata-quirk.patch linux-2.6-build-nonintconfig.patch
linux-2.6-crash-driver.patch linux-2.6-debug-nmi-timeout.patch
linux-2.6-debug-spinlock-taint.patch
linux-2.6-debug-taint-vm.patch
linux-2.6-defaults-fat-utf8.patch linux-2.6-devmem.patch
linux-2.6-execshield.patch
linux-2.6-input-kill-stupid-messages.patch
linux-2.6-net-silence-noisy-printks.patch
linux-2.6-ppc32-ucmpdi2.patch linux-2.6-ps3-ehci-iso.patch
linux-2.6-selinux-mprotect-checks.patch
linux-2.6-serial-460800.patch linux-2.6-silence-noise.patch
linux-2.6-squashfs.patch linux-2.6-unexport-symbols.patch
linux-2.6-utrace-core.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.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-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.patch linux-2.6-wireless.patch
linux-2.6-x86-tune-generic.patch nouveau-drm.patch sources
xen-build-id.patch xen-compile-fix.patch
xen-syms-build-id.patch
Added Files:
Tag: private-markmc-pv-ops-branch
.gitignore gen-patches
linux-2.6-0001-xen-debug-Add-xprintk-to-log-directly-via-hypercall.patch
linux-2.6-0002-xen-dom0-Make-hvc_xen-console-work-for-dom0.patch
linux-2.6-0003-xen-dom0-Initialize-xenbus-for-dom0.patch
linux-2.6-0004-xen-dom0-Set-up-basic-IO-permissions-for-dom0.patch
linux-2.6-0005-xen-dom0-Add-set_fixmap-pv_mmu_ops.patch
linux-2.6-0006-xen-dom0-Add-support-for-the-platform_ops-hypercall.patch
linux-2.6-0007-xen-acpi-Enable-early-access-to-ACPI-tables.patch
linux-2.6-0008-xen-dom0-Add-paravirt_ops-ioremap_page_range-for.patch
linux-2.6-0009-MTRR-use-cpu_callout_map-instead-of-cpu_online_map.patch
linux-2.6-0010-xen-mtrr-Add-mtrr_ops-support-for-Xen-mtrr.patch
linux-2.6-0011-xen-mtrr-Don-t-enable-xen-mtrr-on-bare-metal.patch
linux-2.6-0012-xen-mtrr-set-cpu-in-cpu_callout_map.patch
linux-2.6-0013-xen-mtrr-Clean-up-the-num_var_ranges-CPU_UNKOWN-hac.patch
linux-2.6-0014-xen-mtrr-Use-specific-cpu_has_foo-macros-instead-of.patch
linux-2.6-0015-xen-mtrr-Kill-some-unneccessary-includes.patch
linux-2.6-0016-xen-mtrr-No-need-to-explicitly-set-use_intel_if-0.patch
linux-2.6-0017-xen-mtrr-Use-generic_validate_add_page.patch
linux-2.6-0018-xen-mtrr-Implement-xen_get_free_region.patch
linux-2.6-0019-xen-mtrr-Add-xen_-get-set-_mtrr-implementations.patch
linux-2.6-0020-irq2.diff-from-Juan-Quintela.patch
linux-2.6-0021-xen-dom0-Obvious-cpuid-fix-to-domU-handling.patch
linux-2.6-0022-xen-debug-Diagnose-bind_virq_to_irq-errors.patch
linux-2.6-0023-xen-traps-Revert-Juan-s-traps_32.c-changes-to-debug.patch
linux-2.6-0024-xen-debug-Move-init_apic_mappings-after-trap-init.patch
linux-2.6-0025-xen-debug-Trace-progress-in-trap_init-around-init.patch
linux-2.6-0026-xen-apic-Disable-init_apic_mappings-when-under-CO.patch
linux-2.6-0027-xen-debug-Log-entry-into-virtual-console-s-xen_init.patch
linux-2.6-0028-xen-debug-Log-bind_virq_to_irq-events.patch
linux-2.6-0029-xen-debug-Work-around-USB-issue-triggered-by-Xen-de.patch
linux-2.6-0030-Remove-duplicated-dma_alloc-free_noncoherent-define.patch
linux-2.6-0031-xem-dom0-Add-hypervisor-memory_exchange-descriptor.patch
linux-2.6-0032-xen-dom0-add-virt_to_pfn-macro.patch
linux-2.6-0033-xen-dom0-use-virt_to_pfn-where-appropriate.patch
linux-2.6-0034-xen-dom0-Add-contiguous-region-support.patch
linux-2.6-0035-xen-dom0-Don-t-mask-off-PCD-bits-from-pte-entries.patch
linux-2.6-0036-xen-dom0-Remove-duplicate-xen_store_interface-assig.patch
linux-2.6-0037-xen-dom0-Slightly-re-arrange-xenbus_probe_init-er.patch
linux-2.6-0038-xen-dom0-Use-max_low_pfn-declaration-from-linux-boo.patch
linux-2.6-0039-xen-dma-Add-dma_mapping_ops-indirection-for-32-bit.patch
linux-2.6-0040-xen-dma-Remove-unused-32-bit-dma_ops-map_simple-me.patch
linux-2.6-0041-xen-dma-Initial-commit-of-pci-xen.c-dma-mapping-fun.patch
linux-2.6-0042-xen-dma-Add-calls-to-dma_ops-alloc-free_coherent-ho.patch
linux-2.6-0043-xen-dma-Add-xen_alloc-free_coherent.patch
linux-2.6-0044-xen-dma-Don-t-merge-bios-on-xen-pvops.patch
linux-2.6-0045-xen-dom0-Minor-coding-style-issue-in-ISA-mapping-co.patch
linux-2.6-0046-xen-dom0-Use-i-PAGE_SHIFT-instead-of-PAGE_DOWN-i.patch
linux-2.6-0047-xen-dom0-Match-up-set_pte_mfn-prototype-with-the.patch
linux-2.6-0048-xen-dom0-Reserve-ISA-address-space-earlier.patch
linux-2.6-0049-xen-Add-empty-xenctrl-module.patch
linux-2.6-0050-xen-dom0-Add-proc-xen-capabilities.patch
linux-2.6-0051-xen-Add-proc-xen-privcmd.patch
linux-2.6-0052-xen-dom0-Add-proc-xen-xsd_-port-kva.patch
linux-2.6-0053-xen-Add-proc-xen-xenbus.patch
linux-2.6-0054-xen-Add-dev-xen-evtchn.patch
linux-2.6-0055-xen-Add-__init-__exit-notations-to-xenctrl-function.patch
linux-2.6-0056-xen-Add-Xen-s-sys-hypervisor-interface.patch
linux-2.6-0057-xen-dom0-Add-basic-proc-xen-balloon.patch
linux-2.6-0058-xen-dom0-Re-work-privcmd_ioctl-a-little.patch
linux-2.6-0059-xen-dom0-Add-IOCTL_PRIVCMD_MMAP.patch
linux-2.6-acpi-eeepc-hotkey.patch linux-2.6-agp-mm.patch
linux-2.6-alsa-rc4-mm1.patch
linux-2.6-alsa-support-sis7019.patch linux-2.6-at76.patch
linux-2.6-ath5k-use-soft-wep.patch
linux-2.6-compile-fix-gcc-43.patch
linux-2.6-compile-fixes.patch linux-2.6-dcdbas-autoload.patch
linux-2.6-debug-acpi-os-write-port.patch
linux-2.6-default-mmf_dump_elf_headers.patch
linux-2.6-drm-add-i915-radeon-mdt.patch linux-2.6-drm-mm.patch
linux-2.6-drm-radeon-update.patch
linux-2.6-e1000-corrupt-eeprom-checksum.patch
linux-2.6-epoll-lockdep-annotation.patch
linux-2.6-ext4-linus-git.patch
linux-2.6-ext4-stable-queue.patch
linux-2.6-firewire-git-pending.patch
linux-2.6-firewire-git-update.patch
linux-2.6-gelic-fixups.patch
linux-2.6-gelic-wireless-fix.patch
linux-2.6-gelic-wireless-v2.patch
linux-2.6-git-initial-r500-drm.patch
linux-2.6-i386-vdso-install-unstripped-copies-on-disk.patch
linux-2.6-lirc.patch linux-2.6-netdev-atl2.patch
linux-2.6-netdev-bonding-fix-null-deref.patch
linux-2.6-netdev-e1000-disable-alpm.patch
linux-2.6-pasemi-for-2.6.25.patch
linux-2.6-pasemi-reserve-i2c.patch
linux-2.6-powerpc-bootwrapper.patch
linux-2.6-powerpc-generic-suspend-001-pmu-no-lock-kernel.patch
linux-2.6-powerpc-generic-suspend-002-pmu-remove-dead-code.patch
linux-2.6-powerpc-generic-suspend-003-remove-adb-sleep-notifier.patch
linux-2.6-powerpc-generic-suspend-004-kill-pmu-sleep-notifier.patch
linux-2.6-powerpc-generic-suspend-005-proper-sleep-management.patch
linux-2.6-ppc-rtc.patch
linux-2.6-ps3-legacy-bootloader-hack.patch
linux-2.6-ps3-storage-alias.patch linux-2.6-rndis_wlan.patch
linux-2.6-scsi-mpt-vmware-fix.patch
linux-2.6-selinux-strip-leading-slashes.patch
linux-2.6-smarter-relatime.patch
linux-2.6-usb-ehci-hcd-respect-nousb.patch
linux-2.6-utrace-ptrace-compat-avr32.patch
linux-2.6-utrace-regset-avr32.patch
linux-2.6-utrace-tracehook-avr32.patch
linux-2.6-uvcvideo.patch linux-2.6-wireless-pending.patch
linux-2.6-x86-debug-boot.patch
linux-2.6-xfs-optimize-away-realtime-tests.patch
linux-2.6-xfs-setfattr-32bit-compat.patch
linux-2.6-xfs-xfs_mount-refactor.patch
linux-2.6.24.tar.bz2.sign mirrors upstream upstream-key.gpg
Removed Files:
Tag: private-markmc-pv-ops-branch
config-olpc-generic git-wireless-dev.patch
kernel-2.6.21.7-i686-xen.config
kernel-2.6.21.7-x86_64-xen.config
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-3w-9xxx-mem_len.patch linux-2.6-PT_LOAD-align.patch
linux-2.6-acpi-boot-regression.patch
linux-2.6-acpi-config_pm-poweroff.patch
linux-2.6-acpi-dock-oops.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-amd-disabled-svm-detect-msr-1.patch
linux-2.6-amd-disabled-svm-detect.patch
linux-2.6-ata-call-check-dma-with-qc-prepared.patch
linux-2.6-ata-use-pio-for-non-16-byte-xfers.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-common-uevent.patch
linux-2.6-crap-sysfs-workaround.patch
linux-2.6-crash-driver-xen.patch linux-2.6-cve-2008-0600.patch
linux-2.6-debug-boot-delay.patch
linux-2.6-debug-extra-warnings.patch
linux-2.6-debug-must_check.patch
linux-2.6-debug-slab-backtrace.patch
linux-2.6-debug-sysfs-crash-debugging-xen.patch
linux-2.6-debug-sysfs-crash-debugging.patch
linux-2.6-defaults-nonmi.patch
linux-2.6-defaults-pci_no_msi_mmconf.patch
linux-2.6-defaults-unicode-vt.patch linux-2.6-devmem-xen.patch
linux-2.6-disable-netback-checksum.patch
linux-2.6-dvb-spinlock.patch linux-2.6-execshield-xen.patch
linux-2.6-firewire-be32-fix.patch linux-2.6-firewire.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-gfs2-update.patch
linux-2.6-i82875-edac-pci-setup.patch
linux-2.6-i965gm-support.patch linux-2.6-ibmvscsi-schizo.patch
linux-2.6-kvm-19.patch
linux-2.6-kvm-reinit-real-mode-tss.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-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-libertas.diff linux-2.6-mm-udf-fixes.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-modsign-verify.patch linux-2.6-module_version.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-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-netdev-e1000e-backport.patch
linux-2.6-nfs-missing-braces.patch
linux-2.6-nfs-noreaddirplus.patch linux-2.6-olpc-touchpad.diff
linux-2.6-ondemand-timer.patch linux-2.6-oprofile-0.9.3.patch
linux-2.6-optimise-spinlock-debug.patch
linux-2.6-pmac-zilog.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-reserve-initrd-1.patch
linux-2.6-powerpc-reserve-initrd-2.patch
linux-2.6-powerpc-slabalign.patch
linux-2.6-ppc-data-exception.patch
linux-2.6-proc-self-maps-fix.patch
linux-2.6-ps3-clear-spu-irq.patch
linux-2.6-ps3-device-init.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-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.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-raid-autorun.patch
linux-2.6-scsi-bounce-isa.patch linux-2.6-sha_alignment.patch
linux-2.6-softirq-printout-irq-trace-events.patch
linux-2.6-softlockup-disable.patch
linux-2.6-sumversion-limits-dot-h.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-uevent-ebus.patch linux-2.6-uevent-macio.patch
linux-2.6-uevent-of_platform.patch
linux-2.6-usb-autosuspend-default-disable.patch
linux-2.6-use-build-id-ld-option.patch
linux-2.6-utrace-ptrace-compat-xen.patch
linux-2.6-utrace-recalc_sigpending_and_wake.patch
linux-2.6-utrace-sig_kernel-macros.patch
linux-2.6-utrace-tracehook-xen.patch
linux-2.6-vm-invalidate_mapping_pages-cond-resched.patch
linux-2.6-vm-silence-atomic-alloc-failures.patch
linux-2.6-wakeups-hdaps.patch
linux-2.6-x86-64-edac-support.patch
linux-2.6-x86-64_pmtrace.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-vga-vidfail.patch
linux-2.6-x86_64-silence-up-apic-errors-xen.patch
linux-2.6-x86_64-silence-up-apic-errors.patch
linux-2.6-xen-backwards-time.patch
linux-2.6-xen-blkfront-wait-add.patch
linux-2.6-xen-fix-irq-warn-mismerge.patch
linux-2.6-xen-irq_vector-uninitialize.patch
linux-2.6-xen-paravirt-nographics-pvfb-fix.patch
linux-2.6-xen-privcmd-use-nopfn.patch
linux-2.6-xen-sleazy-fpu-i386.patch
linux-2.6-xen-sleazy-fpu-x86_64.patch
linux-2.6.20.tar.bz2.sign
Log Message:
Sync to kernel-2_6_24-23_fc9 tag of rpms/kernel/devel and
add first round of Xen pv_ops Dom0 support
--- NEW FILE .gitignore ---
clog
GNUmakefile
kernel-2.6.*.config
temp-*
kernel-2.6.24
linux-2.6.24.tar.bz2
xen-3.2.0.tar.gz
--- NEW FILE gen-patches ---
#!/bin/bash
#
# 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
patchbase=10
nextpatch=$patchbase
usepatch()
{
patches[$nextpatch]=$1
nextpatch=$(($nextpatch + 1))
}
lasturl=:
loglines="- Experimental build from git sources ($patchcomment)\\
"
log()
{
local logrev=$1
local logbranch=$3
local ref
ref=`git-symbolic-ref -q $logbranch` && logbranch=$ref
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=$patchbase
while [ $p -lt $nextpatch ]; do
echo "Patch$p: ${patches[$p]}\\"
p=$(($p + 1))
done
}
patch_apply()
{
p=$patchbase
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
patchfile=patch-${base#v}.bz2
fgrep -q $patchfile sources || usepatch $patchfile
log $tag_rev tag $base
done
version=${base#v}
now="`date +'%Y-%m-%d %H:%M %Z'`"
GIT_DIFF_OPTS=-pu
export GIT_DIFF_OPTS
i=0
last_base=$base
last_base_rev=$base_rev
for branch; do
branch_rev=`git-rev-parse "$branch^{}"` || exit 2
merge_base=`git-merge-base $last_base_rev $branch_rev` || {
echo >&2 "No common ancestor for $last_base and $branch"
exit 2
}
if ((i > 0)) && [ "x$merge_base" = "x${merge_rev[$(($i - 1))]}" ]; then
echo >&2 "$last_base is not an ancestor of $branch"
exit 2
fi
merge_rev[$i]=$merge_base
((i++))
last_base=$branch
last_base_rev=$branch_rev
done
merge_rev[$i]=$last_base_rev
test "x${merge_rev[0]}" = "x$base_rev" || {
echo >&2 "$base is not an ancestor of $branch"
exit 2
}
i=1
for branch; do
branch_rev=${merge_rev[$i]}
((i++))
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 --patch-with-stat \
-r "${base_rev}" -r "${branch_rev}" > $file || exit
if [ ! -s $file ]; then
rm -f $file
continue
fi
usepatch $file
log $branch_rev branch $branch
base_rev="$branch_rev"
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/^[^-]*//;s/-/./g'`
logdate=`date -d "$now" +'%a %b %d %Y'`
sed "/%define nopatches/c\\
%define nopatches ${nopatches}\\
%define upstream_branch ${name}\\
%define upstream_branch_tag ${branch_rev}
/^### BRANCH PATCH/a\\
`patch_headers`
###
/^### BRANCH APPLY/a\\
`patch_apply`
###
/^%changelog/a\\
* ${logdate} ${GIT_AUTHOR_NAME} <${GIT_AUTHOR_EMAIL}>\\
$loglines
"
linux-2.6-0001-xen-debug-Add-xprintk-to-log-directly-via-hypercall.patch:
--- NEW FILE linux-2.6-0001-xen-debug-Add-xprintk-to-log-directly-via-hypercall.patch ---
>From cbdf50a0e23b958ec393b044a8414ac24117558e Mon Sep 17 00:00:00 2001
From: Stephen Tweedie <sct redhat com>
Date: Wed, 21 Nov 2007 18:40:31 +0000
Subject: [PATCH] xen debug: Add xprintk to log directly via hypercall
For early debugging, it is useful to have a way of doing debugging output
direct to the hypervisor without having to rely on console being fully
initialised.
Signed-off-by: Stephen Tweedie <sct redhat com>
---
arch/x86/xen/enlighten.c | 32 ++++++++++++++++++++++++++++++++
include/xen/hvc-console.h | 1 +
2 files changed, 33 insertions(+), 0 deletions(-)
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index 79ad152..84f46e2 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -32,6 +32,7 @@
#include <xen/interface/sched.h>
#include <xen/features.h>
#include <xen/page.h>
+#include <xen/hvc-console.h>
#include <asm/paravirt.h>
#include <asm/page.h>
@@ -141,6 +142,37 @@ static void __init xen_banner(void)
printk(KERN_INFO "Hypervisor signature: %s\n", xen_start_info->magic);
}
+static void kcons_write_dom0(const char *s, unsigned int count)
+{
+ int rc;
+
+ while ((count > 0) &&
+ ((rc = HYPERVISOR_console_io(
+ CONSOLEIO_write, count, (char *)s)) > 0)) {
+ count -= rc;
+ s += rc;
+ }
+}
+
+
+/*** Useful function for console debugging -- goes straight to Xen. ***/
+asmlinkage int xprintk(const char *fmt, ...)
+{
+ va_list args;
+ int printk_len;
+ static char printk_buf[1024];
+
+ /* Emit the output into the temporary buffer */
+ va_start(args, fmt);
+ printk_len = vsnprintf(printk_buf, sizeof(printk_buf), fmt, args);
+ va_end(args);
+
+ /* Send the processed output directly to Xen. */
+ kcons_write_dom0(printk_buf, printk_len);
+
+ return 0;
+}
+
static void xen_cpuid(unsigned int *eax, unsigned int *ebx,
unsigned int *ecx, unsigned int *edx)
{
diff --git a/include/xen/hvc-console.h b/include/xen/hvc-console.h
index 21c0ecf..cb7a3c9 100644
--- a/include/xen/hvc-console.h
+++ b/include/xen/hvc-console.h
@@ -2,5 +2,6 @@
#define XEN_HVC_CONSOLE_H
extern struct console xenboot_console;
+extern asmlinkage int xprintk(const char *fmt, ...);
#endif /* XEN_HVC_CONSOLE_H */
--
1.5.4.1
linux-2.6-0002-xen-dom0-Make-hvc_xen-console-work-for-dom0.patch:
--- NEW FILE linux-2.6-0002-xen-dom0-Make-hvc_xen-console-work-for-dom0.patch ---
>From f66e3b5781df65ae5b42eaaa97a5487c45620c6a Mon Sep 17 00:00:00 2001
From: Juan Quintela <quintela redhat com>
Date: Mon, 26 Nov 2007 07:38:29 +0100
Subject: [PATCH] xen dom0: Make hvc_xen console work for dom0.
Signed-off-by: Jeremy Fitzhardinge <jeremy xensource com>
Signed-off-by: Juan Quintela <quintela redhat com>
Signed-off-by: Stephen Tweedie <sct redhat com>
---
arch/x86/xen/events.c | 2 +-
drivers/char/hvc_xen.c | 61 +++++++++++++++++++++++++++++++++++++++++------
include/xen/events.h | 2 +
3 files changed, 56 insertions(+), 9 deletions(-)
diff --git a/arch/x86/xen/events.c b/arch/x86/xen/events.c
index 6d1da58..2bf9731 100644
--- a/arch/x86/xen/events.c
+++ b/arch/x86/xen/events.c
@@ -311,7 +311,7 @@ static int bind_ipi_to_irq(unsigned int ipi, unsigned int cpu)
}
-static int bind_virq_to_irq(unsigned int virq, unsigned int cpu)
+int bind_virq_to_irq(unsigned int virq, unsigned int cpu)
{
struct evtchn_bind_virq bind_virq;
int evtchn, irq;
diff --git a/drivers/char/hvc_xen.c b/drivers/char/hvc_xen.c
index dd68f85..6e85664 100644
--- a/drivers/char/hvc_xen.c
+++ b/drivers/char/hvc_xen.c
@@ -50,7 +50,7 @@ static inline void notify_daemon(void)
notify_remote_via_evtchn(xen_start_info->console.domU.evtchn);
}
-static int write_console(uint32_t vtermno, const char *data, int len)
+static int domU_write_console(uint32_t vtermno, const char *data, int len)
{
struct xencons_interface *intf = xencons_interface();
XENCONS_RING_IDX cons, prod;
@@ -71,7 +71,28 @@ static int write_console(uint32_t vtermno, const char *data, int len)
return sent;
}
-static int read_console(uint32_t vtermno, char *buf, int len)
+static int dom0_write_console(uint32_t vtermno, const char *data, int len)
+{
+ int ret;
+
+ ret = HYPERVISOR_console_io(CONSOLEIO_write, len, (char *)data);
+
+ return ret < 0 ? 0 : len;
+}
+
+static int write_console(uint32_t vtermno, const char *data, int len)
+{
+ int ret;
+
+ if (is_initial_xendomain())
+ ret = dom0_write_console(vtermno, data, len);
+ else
+ ret = domU_write_console(vtermno, data, len);
+
+ return ret;
+}
+
+static int domU_read_console(uint32_t vtermno, char *buf, int len)
{
struct xencons_interface *intf = xencons_interface();
XENCONS_RING_IDX cons, prod;
@@ -92,22 +113,40 @@ static int read_console(uint32_t vtermno, char *buf, int len)
return recv;
}
-static struct hv_ops hvc_ops = {
- .get_chars = read_console,
- .put_chars = write_console,
+static int dom0_read_console(uint32_t vtermno, char *buf, int len)
+{
+ return HYPERVISOR_console_io(CONSOLEIO_read, len, buf);
+}
+
+static struct hv_ops domU_hvc_ops = {
+ .get_chars = domU_read_console,
+ .put_chars = domU_write_console,
+};
+
+static struct hv_ops dom0_hvc_ops = {
+ .get_chars = dom0_read_console,
+ .put_chars = dom0_write_console,
};
static int __init xen_init(void)
{
struct hvc_struct *hp;
+ struct hv_ops *ops;
if (!is_running_on_xen())
return 0;
- xencons_irq = bind_evtchn_to_irq(xen_start_info->console.domU.evtchn);
+ if (is_initial_xendomain()) {
+ ops = &dom0_hvc_ops;
+ xencons_irq = bind_virq_to_irq(VIRQ_CONSOLE, 0);
+ } else {
+ ops = &domU_hvc_ops;
+ xencons_irq = bind_evtchn_to_irq(xen_start_info->console.domU.evtchn);
+ }
+
if (xencons_irq < 0)
xencons_irq = 0 /* NO_IRQ */;
- hp = hvc_alloc(HVC_COOKIE, xencons_irq, &hvc_ops, 256);
+ hp = hvc_alloc(HVC_COOKIE, xencons_irq, ops, 256);
if (IS_ERR(hp))
return PTR_ERR(hp);
@@ -123,10 +162,16 @@ static void __exit xen_fini(void)
static int xen_cons_init(void)
{
+ struct hv_ops *ops;
+
if (!is_running_on_xen())
return 0;
- hvc_instantiate(HVC_COOKIE, 0, &hvc_ops);
+ ops = &domU_hvc_ops;
+ if (is_initial_xendomain())
+ ops = &dom0_hvc_ops;
+
+ hvc_instantiate(HVC_COOKIE, 0, ops);
return 0;
}
diff --git a/include/xen/events.h b/include/xen/events.h
index 2bde54d..0436486 100644
--- a/include/xen/events.h
+++ b/include/xen/events.h
@@ -18,6 +18,8 @@ int bind_evtchn_to_irqhandler(unsigned int evtchn,
irq_handler_t handler,
unsigned long irqflags, const char *devname,
void *dev_id);
+int bind_virq_to_irq(unsigned int virq, unsigned int cpu);
+
int bind_virq_to_irqhandler(unsigned int virq, unsigned int cpu,
irq_handler_t handler,
unsigned long irqflags, const char *devname,
--
1.5.4.1
linux-2.6-0003-xen-dom0-Initialize-xenbus-for-dom0.patch:
--- NEW FILE linux-2.6-0003-xen-dom0-Initialize-xenbus-for-dom0.patch ---
>From a7ff3dba9663a740f85d5bcb71492eb58c03ce4c Mon Sep 17 00:00:00 2001
From: Juan Quintela <quintela redhat com>
Date: Mon, 26 Nov 2007 08:35:10 +0100
Subject: [PATCH] xen dom0: Initialize xenbus for dom0.
Signed-off-by: Jeremy Fitzhardinge <jeremy xensource com>
Signed-off-by: Juan Quintela <quintela redhat com>
---
drivers/xen/xenbus/xenbus_probe.c | 30 +++++++++++++++++++++++++++++-
1 files changed, 29 insertions(+), 1 deletions(-)
diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c
index 4750de3..298c4c8 100644
--- a/drivers/xen/xenbus/xenbus_probe.c
+++ b/drivers/xen/xenbus/xenbus_probe.c
@@ -787,6 +787,7 @@ void xenbus_probe(struct work_struct *unused)
static int __init xenbus_probe_init(void)
{
int err = 0;
+ unsigned long page = 0;
DPRINTK("");
@@ -807,7 +808,31 @@ static int __init xenbus_probe_init(void)
* Domain0 doesn't have a store_evtchn or store_mfn yet.
*/
if (is_initial_xendomain()) {
- /* dom0 not yet supported */
+ struct evtchn_alloc_unbound alloc_unbound;
+
+ /* Allocate page. */
+ page = get_zeroed_page(GFP_KERNEL);
+ if (!page)
+ return -ENOMEM;
+
+ xen_store_mfn = xen_start_info->store_mfn =
+ pfn_to_mfn(virt_to_phys((void *)page) >>
+ PAGE_SHIFT);
+
+ /* Next allocate a local port which xenstored can bind to */
+ alloc_unbound.dom = DOMID_SELF;
+ alloc_unbound.remote_dom = 0;
+
+ err = HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound,
+ &alloc_unbound);
+ if (err == -ENOSYS)
+ goto out_unreg_front;
+
+ BUG_ON(err);
+ xen_store_evtchn = xen_start_info->store_evtchn =
+ alloc_unbound.port;
+
+ xen_store_interface = mfn_to_virt(xen_store_mfn);
} else {
xenstored_ready = 1;
xen_store_evtchn = xen_start_info->store_evtchn;
@@ -835,6 +860,9 @@ static int __init xenbus_probe_init(void)
bus_unregister(&xenbus_frontend.bus);
out_error:
+ if (page != 0)
+ free_page(page);
+
return err;
}
--
1.5.4.1
linux-2.6-0004-xen-dom0-Set-up-basic-IO-permissions-for-dom0.patch:
--- NEW FILE linux-2.6-0004-xen-dom0-Set-up-basic-IO-permissions-for-dom0.patch ---
>From d60e2added25bfb050c8b0bb8b23a2eed234f284 Mon Sep 17 00:00:00 2001
From: Juan Quintela <quintela redhat com>
Date: Mon, 26 Nov 2007 08:53:42 +0100
Subject: [PATCH] xen dom0: Set up basic IO permissions for dom0.
Add the direct mapping area for ISA bus access, and enable IO space
access for the guest when running as dom0.
Signed-off-by: Jeremy Fitzhardinge <jeremy xensource com>
Signed-off-by: Juan Quintela <quintela redhat com>
---
arch/x86/mm/ioremap_32.c | 3 ---
arch/x86/xen/enlighten.c | 21 +++++++++++++++++++++
arch/x86/xen/setup.c | 3 ++-
include/asm-x86/io_32.h | 4 ++++
4 files changed, 27 insertions(+), 4 deletions(-)
diff --git a/arch/x86/mm/ioremap_32.c b/arch/x86/mm/ioremap_32.c
index 0b27831..63a301a 100644
--- a/arch/x86/mm/ioremap_32.c
+++ b/arch/x86/mm/ioremap_32.c
@@ -18,9 +18,6 @@
#include <asm/tlbflush.h>
#include <asm/pgtable.h>
-#define ISA_START_ADDRESS 0xa0000
-#define ISA_END_ADDRESS 0x100000
-
/*
* Generic mapping function (not visible outside):
*/
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index 84f46e2..69a73f0 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -45,6 +45,7 @@
#include <asm/pgtable.h>
#include <asm/tlbflush.h>
#include <asm/reboot.h>
+#include <asm/io.h>
#include "xen-ops.h"
#include "mmu.h"
@@ -860,6 +861,20 @@ static __init void xen_pagetable_setup_done(pgd_t *base)
pin_pagetable_pfn(level, PFN_DOWN(__pa(base)));
}
+
+ /*
+ * If we're dom0, then 1:1 map the ISA machine addresses into
+ * the kernel's address space.
+ */
+ if (is_initial_xendomain()) {
+ unsigned i;
+
+ for(i = ISA_START_ADDRESS; i < ISA_END_ADDRESS; i += PAGE_SIZE)
+ set_pte_mfn(PAGE_OFFSET + i, PFN_DOWN(i), PAGE_KERNEL);
+
+ reserve_bootmem(ISA_START_ADDRESS, ISA_END_ADDRESS - ISA_START_ADDRESS);
+ printk(KERN_INFO "Xen: setup ISA identity maps\n");
+ }
}
/* This is called once we have the cpu_possible_map */
@@ -1211,6 +1226,12 @@ asmlinkage void __init xen_start_kernel(void)
if (xen_feature(XENFEAT_supervisor_mode_kernel))
pv_info.kernel_rpl = 0;
+ if (is_initial_xendomain()) {
+ struct physdev_set_iopl set_iopl;
+ set_iopl.iopl = 1;
+ HYPERVISOR_physdev_op(PHYSDEVOP_set_iopl, &set_iopl);
+ }
+
/* set the limit of our address space */
xen_reserve_top();
diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c
index f84e772..3c84287 100644
--- a/arch/x86/xen/setup.c
+++ b/arch/x86/xen/setup.c
@@ -105,7 +105,8 @@ void __init xen_arch_setup(void)
xen_fill_possible_map();
#endif
- paravirt_disable_iospace();
+ if (!is_initial_xendomain())
+ paravirt_disable_iospace();
fiddle_vdso();
}
diff --git a/include/asm-x86/io_32.h b/include/asm-x86/io_32.h
index fe881cd..e2b916e 100644
--- a/include/asm-x86/io_32.h
+++ b/include/asm-x86/io_32.h
@@ -139,6 +139,10 @@ extern void __iomem *fix_ioremap(unsigned idx, unsigned long phys);
#define dmi_iounmap bt_iounmap
#define dmi_alloc alloc_bootmem
+
+#define ISA_START_ADDRESS 0xa0000
+#define ISA_END_ADDRESS 0x100000
+
/*
* ISA I/O bus memory addresses are 1:1 with the physical address.
*/
--
1.5.4.1
linux-2.6-0005-xen-dom0-Add-set_fixmap-pv_mmu_ops.patch:
--- NEW FILE linux-2.6-0005-xen-dom0-Add-set_fixmap-pv_mmu_ops.patch ---
>From 75eea581acc135d53cdc0985ab8c834259f5474d Mon Sep 17 00:00:00 2001
From: Juan Quintela <quintela redhat com>
Date: Tue, 27 Nov 2007 06:44:53 +0100
Subject: [PATCH] xen dom0: Add set_fixmap pv_mmu_ops.
Adds the logic necessary to map by mfn rather than pfn when we set up
fixmaps to point to IO space.
Signed-off-by: Jeremy Fitzhardinge <jeremy xensource com>
Signed-off-by: Juan Quintela <quintela redhat com>
---
arch/x86/kernel/paravirt_32.c | 2 ++
arch/x86/mm/pgtable_32.c | 15 ++++++++++-----
arch/x86/xen/enlighten.c | 38 ++++++++++++++++++++++++++++++++++----
arch/x86/xen/mmu.c | 30 +-----------------------------
include/asm-x86/fixmap_32.h | 13 +++++++++++--
include/asm-x86/paravirt.h | 13 +++++++++++++
include/asm-x86/pgtable_32.h | 3 +++
7 files changed, 74 insertions(+), 40 deletions(-)
diff --git a/arch/x86/kernel/paravirt_32.c b/arch/x86/kernel/paravirt_32.c
index f500079..9fc62c2 100644
--- a/arch/x86/kernel/paravirt_32.c
+++ b/arch/x86/kernel/paravirt_32.c
@@ -462,6 +462,8 @@ struct pv_mmu_ops pv_mmu_ops = {
.enter = paravirt_nop,
.leave = paravirt_nop,
},
+
+ .set_fixmap = native_set_fixmap,
};
EXPORT_SYMBOL_GPL(pv_time_ops);
diff --git a/arch/x86/mm/pgtable_32.c b/arch/x86/mm/pgtable_32.c
index be61a1d..8892aad 100644
--- a/arch/x86/mm/pgtable_32.c
+++ b/arch/x86/mm/pgtable_32.c
@@ -76,7 +76,7 @@ void show_mem(void)
* Associate a virtual page frame with a given physical page frame
* and protection flags for that frame.
*/
-static void set_pte_pfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags)
+void set_pte_vaddr(unsigned long vaddr, pte_t pteval)
{
pgd_t *pgd;
pud_t *pud;
@@ -99,8 +99,8 @@ static void set_pte_pfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags)
return;
}
pte = pte_offset_kernel(pmd, vaddr);
- if (pgprot_val(flags))
- set_pte_present(&init_mm, vaddr, pte, pfn_pte(pfn, flags));
+ if (pte_val(pteval))
+ set_pte_present(&init_mm, vaddr, pte, pteval);
else
pte_clear(&init_mm, vaddr, pte);
@@ -150,7 +150,7 @@ static int fixmaps;
unsigned long __FIXADDR_TOP = 0xfffff000;
EXPORT_SYMBOL(__FIXADDR_TOP);
-void __set_fixmap (enum fixed_addresses idx, unsigned long phys, pgprot_t flags)
+void __native_set_fixmap(enum fixed_addresses idx, pte_t pte)
{
unsigned long address = __fix_to_virt(idx);
@@ -158,10 +158,15 @@ void __set_fixmap (enum fixed_addresses idx, unsigned long phys, pgprot_t flags)
BUG();
return;
}
- set_pte_pfn(address, phys >> PAGE_SHIFT, flags);
+ set_pte_vaddr(address, pte);
fixmaps++;
}
+void native_set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t flags)
+{
+ __native_set_fixmap(idx, pfn_pte(phys >> PAGE_SHIFT, flags));
+}
+
/**
* reserve_top_address - reserves a hole in the top of kernel address space
* @reserve - size of hole to reserve
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index 69a73f0..7240969 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -183,10 +183,12 @@ static void xen_cpuid(unsigned int *eax, unsigned int *ebx,
* Mask out inconvenient features, to try and disable as many
* unsupported kernel subsystems as possible.
*/
- if (*eax == 1)
- maskedx = ~((1 << X86_FEATURE_APIC) | /* disable APIC */
- (1 << X86_FEATURE_ACPI) | /* disable ACPI */
- (1 << X86_FEATURE_ACC)); /* thermal monitoring */
+ if (*eax == 1) {
+ maskedx = ~(1 << X86_FEATURE_APIC); /* disable local APIC */
+ if (!is_initial_xendomain())
+ maskedx &= ~((1 << X86_FEATURE_ACPI) | /* disable ACPI */
+ (1 << X86_FEATURE_ACC)); /* thermal monitoring */
+ }
asm(XEN_EMULATE_PREFIX "cpuid"
: "=a" (*eax),
@@ -952,6 +954,32 @@ static unsigned xen_patch(u8 type, u16 clobbers, void *insnbuf,
return ret;
}
+static void xen_set_fixmap(unsigned idx, unsigned long phys, pgprot_t prot)
+{
+ pte_t pte;
+
+ phys >>= PAGE_SHIFT;
+
+ switch (idx) {
+#ifdef CONFIG_X86_F00F_BUG
+ case FIX_F00F_IDT:
+#endif
+ case FIX_WP_TEST:
+ case FIX_VDSO:
+#ifdef CONFIG_X86_LOCAL_APIC
+ case FIX_APIC_BASE: /* maps dummy local APIC */
+#endif
+ pte = pfn_pte(phys, prot);
+ break;
+
+ default:
+ pte = mfn_pte(phys, prot);
+ break;
+ }
+
+ __native_set_fixmap(idx, pte);
+}
+
static const struct pv_info xen_info __initdata = {
.paravirt_enabled = 1,
.shared_kernel_pmd = 0,
@@ -1104,6 +1132,8 @@ static const struct pv_mmu_ops xen_mmu_ops __initdata = {
.enter = paravirt_enter_lazy_mmu,
.leave = xen_leave_lazy,
},
+
+ .set_fixmap = xen_set_fixmap,
};
#ifdef CONFIG_SMP
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
index 0ac6c5d..2e28104 100644
--- a/arch/x86/xen/mmu.c
+++ b/arch/x86/xen/mmu.c
@@ -119,35 +119,7 @@ void xen_set_pmd(pmd_t *ptr, pmd_t val)
*/
void set_pte_mfn(unsigned long vaddr, unsigned long mfn, pgprot_t flags)
{
- pgd_t *pgd;
- pud_t *pud;
- pmd_t *pmd;
- pte_t *pte;
-
- pgd = swapper_pg_dir + pgd_index(vaddr);
- if (pgd_none(*pgd)) {
- BUG();
- return;
- }
- pud = pud_offset(pgd, vaddr);
- if (pud_none(*pud)) {
- BUG();
- return;
- }
- pmd = pmd_offset(pud, vaddr);
- if (pmd_none(*pmd)) {
- BUG();
- return;
- }
- pte = pte_offset_kernel(pmd, vaddr);
- /* <mfn,flags> stored as-is, to permit clearing entries */
- xen_set_pte(pte, mfn_pte(mfn, flags));
-
- /*
- * It's enough to flush this one mapping.
- * (PGE mappings get flushed as well)
- */
- __flush_tlb_one(vaddr);
+ set_pte_vaddr(vaddr, mfn_pte(mfn, flags));
}
void xen_set_pte_at(struct mm_struct *mm, unsigned long addr,
diff --git a/include/asm-x86/fixmap_32.h b/include/asm-x86/fixmap_32.h
index 249e753..9ed0e25 100644
--- a/include/asm-x86/fixmap_32.h
+++ b/include/asm-x86/fixmap_32.h
@@ -98,8 +98,17 @@ enum fixed_addresses {
__end_of_fixed_addresses
};
-extern void __set_fixmap (enum fixed_addresses idx,
- unsigned long phys, pgprot_t flags);
+void __native_set_fixmap(enum fixed_addresses idx, pte_t pte);
+void native_set_fixmap(enum fixed_addresses idx,
+ unsigned long phys, pgprot_t flags);
+
+#ifndef CONFIG_PARAVIRT
+static inline void __set_fixmap(enum fixed_addresses idx,
+ unsigned long phys, pgprot_t flags)
+{
+ native_set_fixmap(idx, phys, flags);
+}
+#endif
extern void reserve_top_address(unsigned long reserve);
#define set_fixmap(idx, phys) \
diff --git a/include/asm-x86/paravirt.h b/include/asm-x86/paravirt.h
index f59d370..3b9d5b7 100644
--- a/include/asm-x86/paravirt.h
+++ b/include/asm-x86/paravirt.h
@@ -240,6 +240,13 @@ struct pv_mmu_ops {
#endif
struct pv_lazy_ops lazy_mode;
+
+ /* dom0 ops */
+
+ /* Sometimes the physical address is a pfn, and sometimes its
+ an mfn. We can tell which is which from the index. */
+ void (*set_fixmap)(unsigned /* enum fixed_addresses */ idx,
+ unsigned long phys, pgprot_t flags);
};
/* This contains all the paravirt structures: we get a convenient
@@ -1000,6 +1007,12 @@ static inline void arch_flush_lazy_mmu_mode(void)
}
}
+static inline void __set_fixmap(unsigned /* enum fixed_addresses */ idx,
+ unsigned long phys, pgprot_t flags)
+{
+ pv_mmu_ops.set_fixmap(idx, phys, flags);
+}
+
void _paravirt_nop(void);
#define paravirt_nop ((void *)_paravirt_nop)
diff --git a/include/asm-x86/pgtable_32.h b/include/asm-x86/pgtable_32.h
index ed3e70d..6d3687d 100644
--- a/include/asm-x86/pgtable_32.h
+++ b/include/asm-x86/pgtable_32.h
@@ -483,6 +483,9 @@ do { \
void native_pagetable_setup_start(pgd_t *base);
void native_pagetable_setup_done(pgd_t *base);
+/* Install a pte for a particular vaddr in kernel space. */
+void set_pte_vaddr(unsigned long vaddr, pte_t pte);
+
#ifndef CONFIG_PARAVIRT
static inline void paravirt_pagetable_setup_start(pgd_t *base)
{
--
1.5.4.1
linux-2.6-0006-xen-dom0-Add-support-for-the-platform_ops-hypercall.patch:
--- NEW FILE linux-2.6-0006-xen-dom0-Add-support-for-the-platform_ops-hypercall.patch ---
>From f8db032de9275f8fd65ede35d066e07a1aa0f562 Mon Sep 17 00:00:00 2001
From: Stephen Tweedie <sct redhat com>
Date: Fri, 30 Nov 2007 15:06:30 +0000
Subject: [PATCH] xen dom0: Add support for the platform_ops hypercall
Minimal changes to get platform ops (renamed dom0_ops on pv_ops) working
on pv_ops builds. Pulls in upstream linux-2.6.18-xen.hg's platform.h
Signed-off-by: Stephen Tweedie <sct redhat com>
---
include/asm-x86/xen/hypercall.h | 9 ++
include/xen/interface/platform.h | 232 ++++++++++++++++++++++++++++++++++++++
include/xen/interface/xen.h | 2 +
3 files changed, 243 insertions(+), 0 deletions(-)
create mode 100644 include/xen/interface/platform.h
diff --git a/include/asm-x86/xen/hypercall.h b/include/asm-x86/xen/hypercall.h
index bc0ee7d..0802755 100644
--- a/include/asm-x86/xen/hypercall.h
+++ b/include/asm-x86/xen/hypercall.h
@@ -39,6 +39,7 @@
#include <xen/interface/xen.h>
#include <xen/interface/sched.h>
#include <xen/interface/physdev.h>
+#include <xen/interface/platform.h>
extern struct { char _entry[32]; } hypercall_page[];
@@ -184,6 +185,14 @@ HYPERVISOR_set_timer_op(u64 timeout)
}
static inline int
+HYPERVISOR_dom0_op(
+ struct xen_platform_op *platform_op)
+{
+ platform_op->interface_version = XENPF_INTERFACE_VERSION;
+ return _hypercall1(int, dom0_op, platform_op);
+}
+
+static inline int
HYPERVISOR_set_debugreg(int reg, unsigned long value)
{
return _hypercall2(int, set_debugreg, reg, value);
diff --git a/include/xen/interface/platform.h b/include/xen/interface/platform.h
new file mode 100644
index 0000000..0e80c53
--- /dev/null
+++ b/include/xen/interface/platform.h
@@ -0,0 +1,232 @@
+/******************************************************************************
+ * platform.h
+ *
+ * Hardware platform operations. Intended for use by domain-0 kernel.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Copyright (c) 2002-2006, K Fraser
+ */
+
+#ifndef __XEN_PUBLIC_PLATFORM_H__
+#define __XEN_PUBLIC_PLATFORM_H__
+
+#include "xen.h"
+
+#define XENPF_INTERFACE_VERSION 0x03000001
+
+/*
+ * Set clock such that it would read <secs,nsecs> after 00:00:00 UTC,
+ * 1 January, 1970 if the current system time was <system_time>.
+ */
+#define XENPF_settime 17
+struct xenpf_settime {
+ /* IN variables. */
+ uint32_t secs;
+ uint32_t nsecs;
+ uint64_t system_time;
+};
+typedef struct xenpf_settime xenpf_settime_t;
+DEFINE_GUEST_HANDLE_STRUCT(xenpf_settime_t);
+
+/*
+ * Request memory range (@mfn, @mfn+ nr_mfns-1) to have type @type.
+ * On x86, @type is an architecture-defined MTRR memory type.
+ * On success, returns the MTRR that was used (@reg) and a handle that can
+ * be passed to XENPF_DEL_MEMTYPE to accurately tear down the new setting.
+ * (x86-specific).
+ */
+#define XENPF_add_memtype 31
+struct xenpf_add_memtype {
+ /* IN variables. */
+ unsigned long mfn;
+ uint64_t nr_mfns;
+ uint32_t type;
+ /* OUT variables. */
+ uint32_t handle;
+ uint32_t reg;
+};
+typedef struct xenpf_add_memtype xenpf_add_memtype_t;
+DEFINE_GUEST_HANDLE_STRUCT(xenpf_add_memtype_t);
+
+/*
+ * Tear down an existing memory-range type. If @handle is remembered then it
+ * should be passed in to accurately tear down the correct setting (in case
+ * of overlapping memory regions with differing types). If it is not known
+ * then @handle should be set to zero. In all cases @reg must be set.
+ * (x86-specific).
+ */
+#define XENPF_del_memtype 32
+struct xenpf_del_memtype {
+ /* IN variables. */
+ uint32_t handle;
+ uint32_t reg;
+};
+typedef struct xenpf_del_memtype xenpf_del_memtype_t;
+DEFINE_GUEST_HANDLE_STRUCT(xenpf_del_memtype_t);
+
+/* Read current type of an MTRR (x86-specific). */
+#define XENPF_read_memtype 33
+struct xenpf_read_memtype {
+ /* IN variables. */
+ uint32_t reg;
+ /* OUT variables. */
+ unsigned long mfn;
+ uint64_t nr_mfns;
+ uint32_t type;
+};
+typedef struct xenpf_read_memtype xenpf_read_memtype_t;
+DEFINE_GUEST_HANDLE_STRUCT(xenpf_read_memtype_t);
+
+#define XENPF_microcode_update 35
+struct xenpf_microcode_update {
+ /* IN variables. */
+ GUEST_HANDLE(void) data; /* Pointer to microcode data */
+ uint32_t length; /* Length of microcode data. */
+};
+typedef struct xenpf_microcode_update xenpf_microcode_update_t;
+DEFINE_GUEST_HANDLE_STRUCT(xenpf_microcode_update_t);
+
+#define XENPF_platform_quirk 39
+#define QUIRK_NOIRQBALANCING 1 /* Do not restrict IO-APIC RTE targets */
+#define QUIRK_IOAPIC_BAD_REGSEL 2 /* IO-APIC REGSEL forgets its value */
+#define QUIRK_IOAPIC_GOOD_REGSEL 3 /* IO-APIC REGSEL behaves properly */
+struct xenpf_platform_quirk {
+ /* IN variables. */
+ uint32_t quirk_id;
+};
+typedef struct xenpf_platform_quirk xenpf_platform_quirk_t;
+DEFINE_GUEST_HANDLE_STRUCT(xenpf_platform_quirk_t);
+
+#define XENPF_firmware_info 50
+#define XEN_FW_DISK_INFO 1 /* from int 13 AH=08/41/48 */
+#define XEN_FW_DISK_MBR_SIGNATURE 2 /* from MBR offset 0x1b8 */
+#define XEN_FW_VBEDDC_INFO 3 /* from int 10 AX=4f15 */
+struct xenpf_firmware_info {
+ /* IN variables. */
+ uint32_t type;
+ uint32_t index;
+ /* OUT variables. */
+ union {
+ struct {
+ /* Int13, Fn48: Check Extensions Present. */
+ uint8_t device; /* %dl: bios device number */
+ uint8_t version; /* %ah: major version */
+ uint16_t interface_support; /* %cx: support bitmap */
+ /* Int13, Fn08: Legacy Get Device Parameters. */
+ uint16_t legacy_max_cylinder; /* %cl[7:6]:%ch: max cyl # */
+ uint8_t legacy_max_head; /* %dh: max head # */
+ uint8_t legacy_sectors_per_track; /* %cl[5:0]: max sector # */
+ /* Int13, Fn41: Get Device Parameters (as filled into %ds:%esi). */
+ /* NB. First uint16_t of buffer must be set to buffer size. */
+ GUEST_HANDLE(void) edd_params;
+ } disk_info; /* XEN_FW_DISK_INFO */
+ struct {
+ uint8_t device; /* bios device number */
+ uint32_t mbr_signature; /* offset 0x1b8 in mbr */
+ } disk_mbr_signature; /* XEN_FW_DISK_MBR_SIGNATURE */
+ struct {
+ /* Int10, AX=4F15: Get EDID info. */
+ uint8_t capabilities;
+ uint8_t edid_transfer_time;
+ /* must refer to 128-byte buffer */
+ GUEST_HANDLE(uchar) edid;
+ } vbeddc_info; /* XEN_FW_VBEDDC_INFO */
+ } u;
+};
+typedef struct xenpf_firmware_info xenpf_firmware_info_t;
+DEFINE_GUEST_HANDLE_STRUCT(xenpf_firmware_info_t);
+
+#define XENPF_enter_acpi_sleep 51
+struct xenpf_enter_acpi_sleep {
+ /* IN variables */
+ uint16_t pm1a_cnt_val; /* PM1a control value. */
+ uint16_t pm1b_cnt_val; /* PM1b control value. */
+ uint32_t sleep_state; /* Which state to enter (Sn). */
+ uint32_t flags; /* Must be zero. */
+};
+typedef struct xenpf_enter_acpi_sleep xenpf_enter_acpi_sleep_t;
+DEFINE_GUEST_HANDLE_STRUCT(xenpf_enter_acpi_sleep_t);
+
+#define XENPF_change_freq 52
+struct xenpf_change_freq {
+ /* IN variables */
+ uint32_t flags; /* Must be zero. */
+ uint32_t cpu; /* Physical cpu. */
+ uint64_t freq; /* New frequency (Hz). */
+};
+typedef struct xenpf_change_freq xenpf_change_freq_t;
+DEFINE_GUEST_HANDLE_STRUCT(xenpf_change_freq_t);
+
+/*
+ * Get idle times (nanoseconds since boot) for physical CPUs specified in the
+ * @cpumap_bitmap with range [0 cpumap_nr_cpus-1] The @idletime array is
+ * indexed by CPU number; only entries with the corresponding @cpumap_bitmap
+ * bit set are written to. On return, @cpumap_bitmap is modified so that any
+ * non-existent CPUs are cleared. Such CPUs have their @idletime array entry
+ * cleared.
+ */
+#define XENPF_getidletime 53
+struct xenpf_getidletime {
+ /* IN/OUT variables */
+ /* IN: CPUs to interrogate; OUT: subset of IN which are present */
+ GUEST_HANDLE(uchar) cpumap_bitmap;
+ /* IN variables */
+ /* Size of cpumap bitmap. */
+ uint32_t cpumap_nr_cpus;
+ /* Must be indexable for every cpu in cpumap_bitmap. */
+ GUEST_HANDLE(uint64_t) idletime;
+ /* OUT variables */
+ /* System time when the idletime snapshots were taken. */
+ uint64_t now;
+};
+typedef struct xenpf_getidletime xenpf_getidletime_t;
+DEFINE_GUEST_HANDLE_STRUCT(xenpf_getidletime_t);
+
+struct xen_platform_op {
+ uint32_t cmd;
+ uint32_t interface_version; /* XENPF_INTERFACE_VERSION */
+ union {
+ struct xenpf_settime settime;
+ struct xenpf_add_memtype add_memtype;
+ struct xenpf_del_memtype del_memtype;
+ struct xenpf_read_memtype read_memtype;
+ struct xenpf_microcode_update microcode;
+ struct xenpf_platform_quirk platform_quirk;
+ struct xenpf_firmware_info firmware_info;
+ struct xenpf_enter_acpi_sleep enter_acpi_sleep;
+ struct xenpf_change_freq change_freq;
+ struct xenpf_getidletime getidletime;
+ uint8_t pad[128];
+ } u;
+};
+typedef struct xen_platform_op xen_platform_op_t;
+DEFINE_GUEST_HANDLE_STRUCT(xen_platform_op_t);
+
+#endif /* __XEN_PUBLIC_PLATFORM_H__ */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/include/xen/interface/xen.h b/include/xen/interface/xen.h
index 518a5bf..5f12e21 100644
--- a/include/xen/interface/xen.h
+++ b/include/xen/interface/xen.h
@@ -437,6 +437,8 @@ typedef uint8_t xen_domain_handle_t[16];
#define __mk_unsigned_long(x) x ## UL
#define mk_unsigned_long(x) __mk_unsigned_long(x)
+DEFINE_GUEST_HANDLE(uint64_t);
+
#else /* __ASSEMBLY__ */
/* In assembly code we cannot use C numeric constant suffixes. */
--
1.5.4.1
linux-2.6-0007-xen-acpi-Enable-early-access-to-ACPI-tables.patch:
--- NEW FILE linux-2.6-0007-xen-acpi-Enable-early-access-to-ACPI-tables.patch ---
>From db0d4ab042b1c3585f5e788a4355309d364e634f Mon Sep 17 00:00:00 2001
From: Stephen Tweedie <sct redhat com>
Date: Fri, 7 Dec 2007 11:39:27 +0000
Subject: [PATCH] xen acpi: Enable early access to ACPI tables.
Always use the fixmap remapping to remap ACPI tables during boot in
__acpi_map_table. Tables which are identity-mapped on baremetal may
not be on Xen.
Add xen-specific logic to detect when ioremap is being called on local
RAM.
Use isa_bus_to_virt on ISA regions for consistency with the fixmap code
Use is_local_lowmem() to test for local non-highmem pages in a Xen-
compatible way.
Signed-off-by: Stephen Tweedie <sct redhat com>
---
arch/x86/kernel/acpi/boot.c | 34 +++++++++++++++-------------------
arch/x86/mm/ioremap_32.c | 34 ++++++++++++++++++++++++++--------
2 files changed, 41 insertions(+), 27 deletions(-)
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index 0ca27c7..e59bda5 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -40,6 +40,8 @@
#include <asm/io.h>
#include <asm/mpspec.h>
+#include <asm/xen/hypervisor.h>
+
static int __initdata acpi_force = 0;
#ifdef CONFIG_ACPI
@@ -103,22 +105,6 @@ static u64 acpi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE;
*/
enum acpi_irq_model_id acpi_irq_model = ACPI_IRQ_MODEL_PIC;
-#ifdef CONFIG_X86_64
-
-/* rely on all ACPI tables being in the direct mapping */
-char *__acpi_map_table(unsigned long phys_addr, unsigned long size)
-{
- if (!phys_addr || !size)
- return NULL;
-
- if (phys_addr+size <= (end_pfn_map << PAGE_SHIFT) + PAGE_SIZE)
- return __va(phys_addr);
-
- return NULL;
-}
-
-#else
-
/*
* Temporarily use the virtual area starting from FIX_IO_APIC_BASE_END,
* to map the target physical address. The problem is that set_fixmap()
@@ -136,8 +122,19 @@ char *__acpi_map_table(unsigned long phys, unsigned long size)
unsigned long base, offset, mapped_size;
int idx;
- if (phys + size < 8 * 1024 * 1024)
- return __va(phys);
+ if (!phys || !size)
+ return NULL;
+
+ if (!is_running_on_xen()) {
+#ifdef CONFIG_X86_64
+ /* rely on all ACPI tables being in the direct mapping */
+ if (phys+size <= (end_pfn_map << PAGE_SHIFT) + PAGE_SIZE)
+ return __va(phys);
+#else
+ if (phys + size < 8 * 1024 * 1024)
+ return __va(phys);
+#endif
+ }
offset = phys & (PAGE_SIZE - 1);
mapped_size = PAGE_SIZE - offset;
@@ -158,7 +155,6 @@ char *__acpi_map_table(unsigned long phys, unsigned long size)
return ((unsigned char *)base + offset);
}
-#endif
#ifdef CONFIG_PCI_MMCONFIG
/* The physical address of the MMCONFIG aperture. Set from ACPI tables. */
diff --git a/arch/x86/mm/ioremap_32.c b/arch/x86/mm/ioremap_32.c
index 63a301a..b4e71f4 100644
--- a/arch/x86/mm/ioremap_32.c
+++ b/arch/x86/mm/ioremap_32.c
@@ -18,6 +18,9 @@
#include <asm/tlbflush.h>
#include <asm/pgtable.h>
+#include <asm/xen/hypervisor.h>
+#include <xen/page.h>
+
/*
* Generic mapping function (not visible outside):
*/
@@ -31,6 +34,21 @@
* have to convert them into an offset in a page-aligned mapping, but the
* caller shouldn't need to know that small detail.
*/
+/*
+ * Does @address reside within a non-highmem page that is local to this virtual
+ * machine (i.e., not an I/O page, nor a memory page belonging to another VM).
+ * See the comment that accompanies mfn_to_local_pfn() in page.h to understand
+ * why this works.
+ */
+static inline int is_local_lowmem(unsigned long address)
+{
+ extern unsigned long max_low_pfn;
+ if (is_running_on_xen())
+ return (mfn_to_local_pfn(address >> PAGE_SHIFT) < max_low_pfn);
+ else
+ return (address <= virt_to_phys(high_memory - 1));
+}
+
void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags)
{
void __iomem * addr;
@@ -47,12 +65,12 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l
* Don't remap the low PCI/ISA area, it's always mapped..
*/
if (phys_addr >= ISA_START_ADDRESS && last_addr < ISA_END_ADDRESS)
- return (void __iomem *) phys_to_virt(phys_addr);
+ return (void __iomem *) isa_bus_to_virt(phys_addr);
/*
* Don't allow anybody to remap normal RAM that we're using..
*/
- if (phys_addr <= virt_to_phys(high_memory - 1)) {
+ if (is_local_lowmem(phys_addr)) {
char *t_addr, *t_end;
struct page *page;
@@ -123,8 +141,8 @@ void __iomem *ioremap_nocache (unsigned long phys_addr, unsigned long size)
/* Guaranteed to be > phys_addr, as per __ioremap() */
last_addr = phys_addr + size - 1;
- if (last_addr < virt_to_phys(high_memory) - 1) {
- struct page *ppage = virt_to_page(__va(phys_addr));
+ if (is_local_lowmem(last_addr)) {
+ struct page *ppage = virt_to_page(bus_to_virt(phys_addr));
unsigned long npages;
phys_addr &= PAGE_MASK;
@@ -166,8 +184,8 @@ void iounmap(volatile void __iomem *addr)
* vm_area and by simply returning an address into the kernel mapping
* of ISA space. So handle that here.
*/
- if (addr >= phys_to_virt(ISA_START_ADDRESS) &&
- addr < phys_to_virt(ISA_END_ADDRESS))
+ if (addr >= isa_bus_to_virt(ISA_START_ADDRESS) &&
+ addr < isa_bus_to_virt(ISA_END_ADDRESS))
return;
addr = (volatile void __iomem *)(PAGE_MASK & (unsigned long __force)addr);
@@ -191,8 +209,8 @@ void iounmap(volatile void __iomem *addr)
}
/* Reset the direct mapping. Can block */
- if ((p->flags >> 20) && p->phys_addr < virt_to_phys(high_memory) - 1) {
- change_page_attr(virt_to_page(__va(p->phys_addr)),
+ if ((p->flags >> 20) && is_local_lowmem(p->phys_addr)) {
+ change_page_attr(virt_to_page(bus_to_virt(p->phys_addr)),
get_vm_area_size(p) >> PAGE_SHIFT,
PAGE_KERNEL);
global_flush_tlb();
--
1.5.4.1
linux-2.6-0008-xen-dom0-Add-paravirt_ops-ioremap_page_range-for.patch:
--- NEW FILE linux-2.6-0008-xen-dom0-Add-paravirt_ops-ioremap_page_range-for.patch ---
>From 13d626b80c3668757421f6206f2006e0f49ac7fe Mon Sep 17 00:00:00 2001
From: Stephen Tweedie <sct redhat com>
Date: Fri, 7 Dec 2007 15:27:21 +0000
Subject: [PATCH] xen dom0: Add paravirt_ops ioremap_page_range() for Xen.
Adds a new pv_mmu_ops field for ioremap_page_range, and the necessary
pv-ops plumbing to connect to lib/ioremap.c's default implementation on
baremetal while still getting xen's hypercall-based implementation when
necessary.
Signed-off-by: Stephen Tweedie <sct redhat com>
---
arch/x86/kernel/paravirt_32.c | 1 +
arch/x86/mm/pgtable_32.c | 7 ++
arch/x86/xen/Makefile | 2 +-
arch/x86/xen/enlighten.c | 1 +
arch/x86/xen/ioremap.c | 147 +++++++++++++++++++++++++++++++++++++++++
arch/x86/xen/mmu.h | 3 +
include/asm-x86/fixmap_32.h | 2 +
include/asm-x86/paravirt.h | 10 +++
include/linux/io.h | 12 ++-
lib/ioremap.c | 4 +-
10 files changed, 182 insertions(+), 7 deletions(-)
create mode 100644 arch/x86/xen/ioremap.c
diff --git a/arch/x86/kernel/paravirt_32.c b/arch/x86/kernel/paravirt_32.c
index 9fc62c2..e578f14 100644
--- a/arch/x86/kernel/paravirt_32.c
+++ b/arch/x86/kernel/paravirt_32.c
@@ -464,6 +464,7 @@ struct pv_mmu_ops pv_mmu_ops = {
},
.set_fixmap = native_set_fixmap,
+ .ioremap_page_range = native_ioremap_page_range,
};
EXPORT_SYMBOL_GPL(pv_time_ops);
diff --git a/arch/x86/mm/pgtable_32.c b/arch/x86/mm/pgtable_32.c
index 8892aad..d1ca199 100644
--- a/arch/x86/mm/pgtable_32.c
+++ b/arch/x86/mm/pgtable_32.c
@@ -15,6 +15,7 @@
#include <linux/spinlock.h>
#include <linux/module.h>
#include <linux/quicklist.h>
+#include <linux/io.h>
#include <asm/system.h>
#include <asm/pgtable.h>
@@ -167,6 +168,12 @@ void native_set_fixmap(enum fixed_addresses idx, unsigned long phys, pgprot_t fl
__native_set_fixmap(idx, pfn_pte(phys >> PAGE_SHIFT, flags));
}
+int native_ioremap_page_range(unsigned long addr, unsigned long end,
+ unsigned long phys_addr, pgprot_t prot)
+{
+ return __ioremap_page_range(addr, end, phys_addr, prot);
+}
+
/**
* reserve_top_address - reserves a hole in the top of kernel address space
* @reserve - size of hole to reserve
diff --git a/arch/x86/xen/Makefile b/arch/x86/xen/Makefile
index 343df24..7ef9e01 100644
--- a/arch/x86/xen/Makefile
+++ b/arch/x86/xen/Makefile
@@ -1,4 +1,4 @@
obj-y := enlighten.o setup.o features.o multicalls.o mmu.o \
- events.o time.o manage.o xen-asm.o
+ events.o time.o manage.o xen-asm.o ioremap.o
obj-$(CONFIG_SMP) += smp.o
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index 7240969..b84f57b 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -1134,6 +1134,7 @@ static const struct pv_mmu_ops xen_mmu_ops __initdata = {
},
.set_fixmap = xen_set_fixmap,
+ .ioremap_page_range = xen_ioremap_page_range,
};
#ifdef CONFIG_SMP
diff --git a/arch/x86/xen/ioremap.c b/arch/x86/xen/ioremap.c
new file mode 100644
index 0000000..4cbbca2
--- /dev/null
+++ b/arch/x86/xen/ioremap.c
@@ -0,0 +1,147 @@
+/*
+ * arch/x86/xen/ioremap.c
+ *
+ * Xen-specific paravirt-ops routines to support re-mapping IO memory
+ * to kernel address space so that we can access it within a Xen privileged
+ * domain.
+ *
+ * (C) Copyright 1995 1996 Linus Torvalds
+ */
+
+#include <linux/vmalloc.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/io.h>
+
+#include <asm/fixmap.h>
+#include <asm/cacheflush.h>
+#include <asm/tlbflush.h>
+#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
+
+#include <asm/xen/hypercall.h>
+#include <xen/page.h>
+
+static int direct_remap_area_pte_fn(pte_t *pte,
+ struct page *pmd_page,
+ unsigned long address,
+ void *data)
+{
+ struct mmu_update **v = (struct mmu_update **)data;
+
+ BUG_ON(!pte_none(*pte));
+
+ (*v)->ptr = ((u64)pfn_to_mfn(page_to_pfn(pmd_page)) <<
+ PAGE_SHIFT) | ((unsigned long)pte & ~PAGE_MASK);
+ (*v)++;
+
+ return 0;
+}
+
+static int __direct_remap_pfn_range(struct mm_struct *mm,
+ unsigned long address,
+ unsigned long mfn,
+ unsigned long size,
+ pgprot_t prot,
+ domid_t domid)
+{
+ int rc;
+ unsigned long i, start_address;
+ struct mmu_update *u, *v, *w;
+
+ u = v = w = (struct mmu_update *)__get_free_page(GFP_KERNEL|__GFP_REPEAT);
+ if (u == NULL)
+ return -ENOMEM;
+
+ start_address = address;
+
+ flush_cache_all();
+
+ for (i = 0; i < size; i += PAGE_SIZE) {
+ if ((v - u) == (PAGE_SIZE / sizeof(struct mmu_update))) {
+ /* Flush a full batch after filling in the PTE ptrs. */
+ rc = apply_to_page_range(mm, start_address,
+ address - start_address,
+ direct_remap_area_pte_fn, &w);
+ if (rc)
+ goto out;
+ rc = -EFAULT;
+ if (HYPERVISOR_mmu_update(u, v - u, NULL, domid) < 0)
+ goto out;
+ v = w = u;
+ start_address = address;
+ }
+
+ /*
+ * Fill in the machine address: PTE ptr is done later by
+ * apply_to_page_range().
+ */
+ v->val = pte_val_ma(mfn_pte(mfn, prot));
+
+ mfn++;
+ address += PAGE_SIZE;
+ v++;
+ }
+
+ if (v != u) {
+ /* Final batch. */
+ rc = apply_to_page_range(mm, start_address,
+ address - start_address,
+ direct_remap_area_pte_fn, &w);
+ if (rc)
+ goto out;
+ rc = -EFAULT;
+ if (unlikely(HYPERVISOR_mmu_update(u, v - u, NULL, domid) < 0))
+ goto out;
+ }
+
+ rc = 0;
+
+ out:
+ flush_tlb_all();
+
+ free_page((unsigned long)u);
+
+ return rc;
+}
+
+/*
+ * Does @address reside within a non-highmem page that is local to this virtual
+ * machine (i.e., not an I/O page, nor a memory page belonging to another VM).
+ * See the comment that accompanies mfn_to_local_pfn() in page.h to understand
+ * why this works.
+ */
+static inline int is_local_lowmem(unsigned long address)
+{
+ extern unsigned long max_low_pfn;
+ return (mfn_to_local_pfn(address >> PAGE_SHIFT) < max_low_pfn);
+}
+
+/*
+ * Remap an arbitrary physical address space into the kernel virtual
+ * address space. Needed when the kernel wants to access high addresses
+ * directly.
+ *
+ * NOTE! We need to allow non-page-aligned mappings too: we will obviously
+ * have to convert them into an offset in a page-aligned mapping, but the
+ * caller shouldn't need to know that small detail.
+ */
+int xen_ioremap_page_range(unsigned long addr, unsigned long end,
+ unsigned long phys_addr, pgprot_t prot)
+{
+ domid_t domid = DOMID_IO;
+ int rc;
+
+ if (is_local_lowmem(phys_addr))
+ domid = DOMID_SELF;
+
+ rc = __direct_remap_pfn_range(&init_mm, (unsigned long)addr,
+ phys_addr>>PAGE_SHIFT,
+ end-addr, prot, domid);
+
+ if (rc)
+ vunmap((void __force *) addr);
+ return rc;
+}
+
diff --git a/arch/x86/xen/mmu.h b/arch/x86/xen/mmu.h
index c9ff27f..8594c92 100644
--- a/arch/x86/xen/mmu.h
+++ b/arch/x86/xen/mmu.h
@@ -57,4 +57,7 @@ pmd_t xen_make_pmd(unsigned long);
pgd_t xen_make_pgd(unsigned long);
#endif
+extern int xen_ioremap_page_range(unsigned long addr, unsigned long end,
+ unsigned long phys_addr, pgprot_t prot);
+
#endif /* _XEN_MMU_H */
diff --git a/include/asm-x86/fixmap_32.h b/include/asm-x86/fixmap_32.h
index 9ed0e25..4517c72 100644
--- a/include/asm-x86/fixmap_32.h
+++ b/include/asm-x86/fixmap_32.h
@@ -101,6 +101,8 @@ enum fixed_addresses {
void __native_set_fixmap(enum fixed_addresses idx, pte_t pte);
void native_set_fixmap(enum fixed_addresses idx,
unsigned long phys, pgprot_t flags);
+int native_ioremap_page_range(unsigned long addr, unsigned long end,
+ unsigned long phys_addr, pgprot_t prot);
#ifndef CONFIG_PARAVIRT
static inline void __set_fixmap(enum fixed_addresses idx,
diff --git a/include/asm-x86/paravirt.h b/include/asm-x86/paravirt.h
index 3b9d5b7..fd17cf4 100644
--- a/include/asm-x86/paravirt.h
+++ b/include/asm-x86/paravirt.h
@@ -247,6 +247,9 @@ struct pv_mmu_ops {
an mfn. We can tell which is which from the index. */
void (*set_fixmap)(unsigned /* enum fixed_addresses */ idx,
unsigned long phys, pgprot_t flags);
+ int (*ioremap_page_range)(unsigned long addr, unsigned long end,
+ unsigned long phys_addr, pgprot_t prot);
+
};
/* This contains all the paravirt structures: we get a convenient
@@ -1013,6 +1016,13 @@ static inline void __set_fixmap(unsigned /* enum fixed_addresses */ idx,
pv_mmu_ops.set_fixmap(idx, phys, flags);
}
+#define __HAVE_ARCH_IOREMAP_PAGE_RANGE
+static inline int ioremap_page_range(unsigned long addr, unsigned long end,
+ unsigned long phys_addr, pgprot_t prot)
+{
+ return pv_mmu_ops.ioremap_page_range(addr, end, phys_addr, prot);
+}
+
void _paravirt_nop(void);
#define paravirt_nop ((void *)_paravirt_nop)
diff --git a/include/linux/io.h b/include/linux/io.h
index e3b2dda..b8abe3d 100644
--- a/include/linux/io.h
+++ b/include/linux/io.h
@@ -28,16 +28,20 @@ void __iowrite32_copy(void __iomem *to, const void *from, size_t count);
void __iowrite64_copy(void __iomem *to, const void *from, size_t count);
#ifdef CONFIG_MMU
-int ioremap_page_range(unsigned long addr, unsigned long end,
- unsigned long phys_addr, pgprot_t prot);
+int __ioremap_page_range(unsigned long addr, unsigned long end,
+ unsigned long phys_addr, pgprot_t prot);
#else
-static inline int ioremap_page_range(unsigned long addr, unsigned long end,
- unsigned long phys_addr, pgprot_t prot)
+static inline int __ioremap_page_range(unsigned long addr, unsigned long end,
+ unsigned long phys_addr, pgprot_t prot)
{
return 0;
}
#endif
+#ifndef __HAVE_ARCH_IOREMAP_PAGE_RANGE
+#define ioremap_page_range __ioremap_page_range
+#endif
+
/*
* Managed iomap interface
*/
diff --git a/lib/ioremap.c b/lib/ioremap.c
index 14c6078..4106cb0 100644
--- a/lib/ioremap.c
+++ b/lib/ioremap.c
@@ -66,8 +66,8 @@ static inline int ioremap_pud_range(pgd_t *pgd, unsigned long addr,
return 0;
}
-int ioremap_page_range(unsigned long addr,
- unsigned long end, unsigned long phys_addr, pgprot_t prot)
+int __ioremap_page_range(unsigned long addr, unsigned long end,
+ unsigned long phys_addr, pgprot_t prot)
{
pgd_t *pgd;
unsigned long start;
--
1.5.4.1
linux-2.6-0009-MTRR-use-cpu_callout_map-instead-of-cpu_online_map.patch:
--- NEW FILE linux-2.6-0009-MTRR-use-cpu_callout_map-instead-of-cpu_online_map.patch ---
>From aa1ebf6fb1281589541682a4dbaafcf048695141 Mon Sep 17 00:00:00 2001
From: Mark McLoughlin <markmc redhat com>
Date: Wed, 30 Jan 2008 13:25:36 +0000
Subject: [PATCH] MTRR: use cpu_callout_map instead of cpu_online_map
During mtrr_restore() only the BP is set in cpu_online_map,
so we need to use cpu_callout_map as a map of CPUs on which
to restore the MTRRs.
The code already uses num_booting_cpus() for this reason, but
it then sends IPIs to the CPUs in cpu_online_map rather than
cpu_callout_map.
Signed-off-by: Mark McLoughlin <markmc redhat com>
---
arch/x86/kernel/cpu/mtrr/main.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/arch/x86/kernel/cpu/mtrr/main.c b/arch/x86/kernel/cpu/mtrr/main.c
index 3b20613..4662ba3 100644
--- a/arch/x86/kernel/cpu/mtrr/main.c
+++ b/arch/x86/kernel/cpu/mtrr/main.c
@@ -232,7 +232,7 @@ static void set_mtrr(unsigned int reg, unsigned long base,
atomic_set(&data.gate,0);
/* Start the ball rolling on other CPUs */
- if (smp_call_function(ipi_handler, &data, 1, 0) != 0)
+ if (smp_call_function_mask(cpu_callout_map, ipi_handler, &data, 0) != 0)
panic("mtrr: timed out waiting for other CPUs\n");
local_irq_save(flags);
--
1.5.4.1
linux-2.6-0010-xen-mtrr-Add-mtrr_ops-support-for-Xen-mtrr.patch:
--- NEW FILE linux-2.6-0010-xen-mtrr-Add-mtrr_ops-support-for-Xen-mtrr.patch ---
>From 75ca621fd427a007e4b9117e3e3bd3dc89f23567 Mon Sep 17 00:00:00 2001
From: Stephen Tweedie <sct redhat com>
Date: Mon, 10 Dec 2007 11:32:15 +0000
Subject: [PATCH] xen mtrr: Add mtrr_ops support for Xen mtrr
Add a Xen mtrr type, and reorganise mtrr initialisation slightly to allow the
mtrr driver to set up num_var_ranges (Xen needs to do this by querying the
hypervisor itself.)
Only the boot path is handled for now: we set up a xen-specific mtrr_if
and set up the mtrr tables based on hypervisor information, but we don't
yet handle mtrr entry add/delete.
Signed-off-by: Stephen Tweedie <sct redhat com>
---
arch/x86/kernel/cpu/mtrr/Makefile | 1 +
arch/x86/kernel/cpu/mtrr/main.c | 30 ++++++++++++++++---
arch/x86/kernel/cpu/mtrr/xen.c | 57 +++++++++++++++++++++++++++++++++++++
3 files changed, 83 insertions(+), 5 deletions(-)
create mode 100644 arch/x86/kernel/cpu/mtrr/xen.c
diff --git a/arch/x86/kernel/cpu/mtrr/Makefile b/arch/x86/kernel/cpu/mtrr/Makefile
index 191fc05..81db513 100644
--- a/arch/x86/kernel/cpu/mtrr/Makefile
+++ b/arch/x86/kernel/cpu/mtrr/Makefile
@@ -1,3 +1,4 @@
obj-y := main.o if.o generic.o state.o
obj-$(CONFIG_X86_32) += amd.o cyrix.o centaur.o
+obj-$(CONFIG_XEN) += xen.o
diff --git a/arch/x86/kernel/cpu/mtrr/main.c b/arch/x86/kernel/cpu/mtrr/main.c
index 4662ba3..c5e0578 100644
--- a/arch/x86/kernel/cpu/mtrr/main.c
+++ b/arch/x86/kernel/cpu/mtrr/main.c
@@ -572,6 +572,7 @@ EXPORT_SYMBOL(mtrr_del);
extern void amd_init_mtrr(void);
extern void cyrix_init_mtrr(void);
extern void centaur_init_mtrr(void);
+extern void xen_init_mtrr(void);
static void __init init_ifs(void)
{
@@ -580,6 +581,9 @@ static void __init init_ifs(void)
cyrix_init_mtrr();
centaur_init_mtrr();
#endif
+#ifdef CONFIG_XEN
+ xen_init_mtrr();
+#endif
}
/* The suspend/resume methods are only for CPU without MTRR. CPU using generic
@@ -635,16 +639,14 @@ static struct sysdev_driver mtrr_sysdev_driver = {
/**
- * mtrr_bp_init - initialize mtrrs on the boot CPU
+ * mtrr_bp_detect - detect mtrr hardware on the boot CPU
*
* This needs to be called early; before any of the other CPUs are
* initialized (i.e. before smp_init()).
*
*/
-void __init mtrr_bp_init(void)
+static void __init mtrr_bp_detect(void)
{
- init_ifs();
-
if (cpu_has_mtrr) {
mtrr_if = &generic_mtrr_ops;
size_or_mask = 0xff000000; /* 36 bits */
@@ -701,9 +703,27 @@ void __init mtrr_bp_init(void)
break;
}
}
+}
+
+/**
+ * mtrr_bp_init - initialize mtrrs on the boot CPU
+ *
+ * This needs to be called early; before any of the other CPUs are
+ * initialized (i.e. before smp_init()).
+ *
+ */
+void __init mtrr_bp_init(void)
+{
+ init_ifs();
+
+ if (!mtrr_if)
+ mtrr_bp_detect();
if (mtrr_if) {
- set_num_var_ranges();
+ /* Xen pv_ops will set the mtrr CPU to unknown, but will
+ * also initialise the num_var_ranges for us */
+ if (!is_cpu(UNKNOWN))
+ set_num_var_ranges();
init_table();
if (use_intel())
get_mtrr_state();
diff --git a/arch/x86/kernel/cpu/mtrr/xen.c b/arch/x86/kernel/cpu/mtrr/xen.c
new file mode 100644
index 0000000..7011195
--- /dev/null
+++ b/arch/x86/kernel/cpu/mtrr/xen.c
@@ -0,0 +1,57 @@
+#include <linux/init.h>
+#include <linux/proc_fs.h>
+#include <linux/ctype.h>
+#include <linux/module.h>
+#include <linux/seq_file.h>
+#include <asm/uaccess.h>
+#include <linux/mutex.h>
+
+#include <asm/mtrr.h>
+#include "mtrr.h"
+
+#include <xen/interface/platform.h>
+#include <asm/xen/hypervisor.h>
+#include <asm/xen/hypercall.h>
+
+/* DOM0 TODO: Need to fill in the remaining mtrr methods to have full
+ * working userland mtrr support. */
+static struct mtrr_ops xen_mtrr_ops = {
+ .vendor = X86_VENDOR_UNKNOWN,
+// .set = xen_set_mtrr,
+// .get = xen_get_mtrr,
+ .get_free_region = generic_get_free_region,
+// .validate_add_page = xen_validate_add_page,
+ .have_wrcomb = positive_have_wrcomb,
+ .use_intel_if = 0
+};
+
+static int __init xen_num_var_ranges(void)
+{
+ int ranges;
+ struct xen_platform_op op;
+
+ for (ranges = 0; ; ranges++) {
+ op.cmd = XENPF_read_memtype;
+ op.u.read_memtype.reg = ranges;
+ if (HYPERVISOR_dom0_op(&op) != 0)
+ break;
+ }
+ return ranges;
+}
+
+void __init xen_init_mtrr(void)
+{
+ struct cpuinfo_x86 *c = &boot_cpu_data;
+
+ if (!is_initial_xendomain())
+ return;
+
+ if ((!cpu_has(c, X86_FEATURE_MTRR)) &&
+ (!cpu_has(c, X86_FEATURE_K6_MTRR)) &&
+ (!cpu_has(c, X86_FEATURE_CYRIX_ARR)) &&
+ (!cpu_has(c, X86_FEATURE_CENTAUR_MCR)))
+ return;
+
+ mtrr_if = &xen_mtrr_ops;
+ num_var_ranges = xen_num_var_ranges();
+}
--
1.5.4.1
linux-2.6-0011-xen-mtrr-Don-t-enable-xen-mtrr-on-bare-metal.patch:
--- NEW FILE linux-2.6-0011-xen-mtrr-Don-t-enable-xen-mtrr-on-bare-metal.patch ---
>From 514160c53a50854b774ade0621c03693dbbee961 Mon Sep 17 00:00:00 2001
From: Stephen Tweedie <sct redhat com>
Date: Wed, 12 Dec 2007 14:31:16 +0000
Subject: [PATCH] xen mtrr: Don't enable xen mtrr on bare metal
is_initial_xendomain() doesn't return valid results unless we're running
on Xen, so it's not a sufficient test for a Xen dom0 on its own: we need
to test separately for is_running_on_xen() first. Without that, we end
up setting xen mtrr behaviour on baremetal systems.
Signed-off-by: Stephen Tweedie <sct redhat com>
---
arch/x86/kernel/cpu/mtrr/xen.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/arch/x86/kernel/cpu/mtrr/xen.c b/arch/x86/kernel/cpu/mtrr/xen.c
index 7011195..4ee9a0f 100644
--- a/arch/x86/kernel/cpu/mtrr/xen.c
+++ b/arch/x86/kernel/cpu/mtrr/xen.c
@@ -43,7 +43,7 @@ void __init xen_init_mtrr(void)
{
struct cpuinfo_x86 *c = &boot_cpu_data;
- if (!is_initial_xendomain())
+ if (!is_running_on_xen() || !is_initial_xendomain())
return;
if ((!cpu_has(c, X86_FEATURE_MTRR)) &&
--
1.5.4.1
linux-2.6-0012-xen-mtrr-set-cpu-in-cpu_callout_map.patch:
--- NEW FILE linux-2.6-0012-xen-mtrr-set-cpu-in-cpu_callout_map.patch ---
>From 2117cdc21eebec01e0aaa592136a8845886d31f8 Mon Sep 17 00:00:00 2001
From: Mark McLoughlin <markmc redhat com>
Date: Wed, 30 Jan 2008 13:18:23 +0000
Subject: [PATCH] xen mtrr: set cpu in cpu_callout_map
The MTRR code uses num_booting_cpus() so make Xen
update cpu_callout_map as it brings cpus up.
Signed-off-by: Mark McLoughlin <markmc redhat com>
---
arch/x86/xen/smp.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c
index c1b131b..e731309 100644
--- a/arch/x86/xen/smp.c
+++ b/arch/x86/xen/smp.c
@@ -198,6 +198,7 @@ void __init xen_smp_prepare_cpus(unsigned int max_cpus)
if (IS_ERR(idle))
panic("failed fork for CPU %d", cpu);
+ cpu_set(cpu, cpu_callout_map);
cpu_set(cpu, cpu_present_map);
}
--
1.5.4.1
linux-2.6-0013-xen-mtrr-Clean-up-the-num_var_ranges-CPU_UNKOWN-hac.patch:
--- NEW FILE linux-2.6-0013-xen-mtrr-Clean-up-the-num_var_ranges-CPU_UNKOWN-hac.patch ---
>From d79941eb28132b96b50cd3e7d37c38e667551878 Mon Sep 17 00:00:00 2001
From: Mark McLoughlin <markmc redhat com>
Date: Mon, 28 Jan 2008 18:55:06 +0000
Subject: [PATCH] xen mtrr: Clean up the num_var_ranges/CPU_UNKOWN hack
Move the CPU_UNKNOWN hack into set_var_num_ranges()
and only enable it with CONFIG_XEN
Signed-off-by: Mark McLoughlin <markmc redhat com>
---
arch/x86/kernel/cpu/mtrr/main.c | 13 +++++++++----
1 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/arch/x86/kernel/cpu/mtrr/main.c b/arch/x86/kernel/cpu/mtrr/main.c
index c5e0578..3ac6ed8 100644
--- a/arch/x86/kernel/cpu/mtrr/main.c
+++ b/arch/x86/kernel/cpu/mtrr/main.c
@@ -107,6 +107,14 @@ static void __init set_num_var_ranges(void)
{
unsigned long config = 0, dummy;
+#ifdef CONFIG_XEN
+ /* Xen pv_ops will set the mtrr CPU to unknown, but will
+ * also initialise the num_var_ranges for us
+ */
+ if (is_cpu(UNKNOWN))
+ return;
+#endif
+
if (use_intel()) {
rdmsr(MTRRcap_MSR, config, dummy);
} else if (is_cpu(AMD))
@@ -720,10 +728,7 @@ void __init mtrr_bp_init(void)
mtrr_bp_detect();
if (mtrr_if) {
- /* Xen pv_ops will set the mtrr CPU to unknown, but will
- * also initialise the num_var_ranges for us */
- if (!is_cpu(UNKNOWN))
- set_num_var_ranges();
+ set_num_var_ranges();
init_table();
if (use_intel())
get_mtrr_state();
--
1.5.4.1
linux-2.6-0014-xen-mtrr-Use-specific-cpu_has_foo-macros-instead-of.patch:
--- NEW FILE linux-2.6-0014-xen-mtrr-Use-specific-cpu_has_foo-macros-instead-of.patch ---
>From a658c6d3c92f86e2789d2ac0ce9197ad76879cb7 Mon Sep 17 00:00:00 2001
From: Mark McLoughlin <markmc redhat com>
Date: Mon, 28 Jan 2008 18:40:06 +0000
Subject: [PATCH] xen mtrr: Use specific cpu_has_foo macros instead of generic cpu_has()
Signed-off-by: Mark McLoughlin <markmc redhat com>
---
arch/x86/kernel/cpu/mtrr/xen.c | 10 ++++------
1 files changed, 4 insertions(+), 6 deletions(-)
diff --git a/arch/x86/kernel/cpu/mtrr/xen.c b/arch/x86/kernel/cpu/mtrr/xen.c
index 4ee9a0f..a693a63 100644
--- a/arch/x86/kernel/cpu/mtrr/xen.c
+++ b/arch/x86/kernel/cpu/mtrr/xen.c
@@ -41,15 +41,13 @@ static int __init xen_num_var_ranges(void)
void __init xen_init_mtrr(void)
{
- struct cpuinfo_x86 *c = &boot_cpu_data;
-
if (!is_running_on_xen() || !is_initial_xendomain())
return;
- if ((!cpu_has(c, X86_FEATURE_MTRR)) &&
- (!cpu_has(c, X86_FEATURE_K6_MTRR)) &&
- (!cpu_has(c, X86_FEATURE_CYRIX_ARR)) &&
- (!cpu_has(c, X86_FEATURE_CENTAUR_MCR)))
+ if (!cpu_has_mtrr &&
+ !cpu_has_k6_mtrr &&
+ !cpu_has_cyrix_arr &&
+ !cpu_has_centaur_mcr)
return;
mtrr_if = &xen_mtrr_ops;
--
1.5.4.1
linux-2.6-0015-xen-mtrr-Kill-some-unneccessary-includes.patch:
--- NEW FILE linux-2.6-0015-xen-mtrr-Kill-some-unneccessary-includes.patch ---
>From 7f0aef7d0e4883c19002ca52f1766df4713de1f4 Mon Sep 17 00:00:00 2001
From: Mark McLoughlin <markmc redhat com>
Date: Mon, 28 Jan 2008 19:05:11 +0000
Subject: [PATCH] xen mtrr: Kill some unneccessary includes
Signed-off-by: Mark McLoughlin <markmc redhat com>
---
arch/x86/kernel/cpu/mtrr/xen.c | 8 +-------
1 files changed, 1 insertions(+), 7 deletions(-)
diff --git a/arch/x86/kernel/cpu/mtrr/xen.c b/arch/x86/kernel/cpu/mtrr/xen.c
index a693a63..d1197ff 100644
--- a/arch/x86/kernel/cpu/mtrr/xen.c
+++ b/arch/x86/kernel/cpu/mtrr/xen.c
@@ -1,12 +1,6 @@
#include <linux/init.h>
-#include <linux/proc_fs.h>
-#include <linux/ctype.h>
-#include <linux/module.h>
-#include <linux/seq_file.h>
-#include <asm/uaccess.h>
-#include <linux/mutex.h>
-
-#include <asm/mtrr.h>
+#include <linux/mm.h>
+
#include "mtrr.h"
#include <xen/interface/platform.h>
--
1.5.4.1
linux-2.6-0016-xen-mtrr-No-need-to-explicitly-set-use_intel_if-0.patch:
--- NEW FILE linux-2.6-0016-xen-mtrr-No-need-to-explicitly-set-use_intel_if-0.patch ---
>From acaa2ebcc82e41a5e7adb9ec6223aa96f6d7a246 Mon Sep 17 00:00:00 2001
From: Mark McLoughlin <markmc redhat com>
Date: Mon, 28 Jan 2008 18:39:29 +0000
Subject: [PATCH] xen mtrr: No need to explicitly set use_intel_if = 0
Signed-off-by: Mark McLoughlin <markmc redhat com>
---
arch/x86/kernel/cpu/mtrr/xen.c | 1 -
1 files changed, 0 insertions(+), 1 deletions(-)
diff --git a/arch/x86/kernel/cpu/mtrr/xen.c b/arch/x86/kernel/cpu/mtrr/xen.c
index d1197ff..726d6ac 100644
--- a/arch/x86/kernel/cpu/mtrr/xen.c
+++ b/arch/x86/kernel/cpu/mtrr/xen.c
@@ -16,7 +16,6 @@ static struct mtrr_ops xen_mtrr_ops = {
.get_free_region = generic_get_free_region,
// .validate_add_page = xen_validate_add_page,
.have_wrcomb = positive_have_wrcomb,
- .use_intel_if = 0
};
static int __init xen_num_var_ranges(void)
--
1.5.4.1
linux-2.6-0017-xen-mtrr-Use-generic_validate_add_page.patch:
--- NEW FILE linux-2.6-0017-xen-mtrr-Use-generic_validate_add_page.patch ---
>From 80001f5436ec01d4e0291c2e2bc499c7a92a0608 Mon Sep 17 00:00:00 2001
From: Mark McLoughlin <markmc redhat com>
Date: Tue, 29 Jan 2008 17:43:25 +0000
Subject: [PATCH] xen mtrr: Use generic_validate_add_page()
The hypervisor already performs the same validation, but
better to do it early before getting to the range combining
code.
Signed-off-by: Mark McLoughlin <markmc redhat com>
---
arch/x86/kernel/cpu/mtrr/xen.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/arch/x86/kernel/cpu/mtrr/xen.c b/arch/x86/kernel/cpu/mtrr/xen.c
index 726d6ac..eff6fd7 100644
--- a/arch/x86/kernel/cpu/mtrr/xen.c
+++ b/arch/x86/kernel/cpu/mtrr/xen.c
@@ -14,7 +14,7 @@ static struct mtrr_ops xen_mtrr_ops = {
// .set = xen_set_mtrr,
// .get = xen_get_mtrr,
.get_free_region = generic_get_free_region,
-// .validate_add_page = xen_validate_add_page,
+ .validate_add_page = generic_validate_add_page,
.have_wrcomb = positive_have_wrcomb,
};
--
1.5.4.1
linux-2.6-0018-xen-mtrr-Implement-xen_get_free_region.patch:
--- NEW FILE linux-2.6-0018-xen-mtrr-Implement-xen_get_free_region.patch ---
>From 8f789415ce84a9619dc6c0193217b1a659ac19f7 Mon Sep 17 00:00:00 2001
From: Mark McLoughlin <markmc redhat com>
Date: Wed, 30 Jan 2008 09:40:33 +0000
Subject: [PATCH] xen mtrr: Implement xen_get_free_region()
When an already set MTRR is being changed, we need to
first unset, since Xen also maintains a usage count.
Signed-off-by: Mark McLoughlin <markmc redhat com>
---
arch/x86/kernel/cpu/mtrr/xen.c | 27 ++++++++++++++++++++++++++-
1 files changed, 26 insertions(+), 1 deletions(-)
diff --git a/arch/x86/kernel/cpu/mtrr/xen.c b/arch/x86/kernel/cpu/mtrr/xen.c
index eff6fd7..6998e00 100644
--- a/arch/x86/kernel/cpu/mtrr/xen.c
+++ b/arch/x86/kernel/cpu/mtrr/xen.c
@@ -7,13 +7,38 @@
#include <asm/xen/hypervisor.h>
#include <asm/xen/hypercall.h>
+static int xen_get_free_region(unsigned long base, unsigned long size, int replace_reg)
+{
+ struct xen_platform_op op;
+ int error;
+
+ if (replace_reg < 0)
+ return generic_get_free_region(base, size, -1);
+
+ /* If we're replacing the contents of a register,
+ * we need to first unset it since Xen also keeps
+ * a usage count.
+ */
+ op.cmd = XENPF_del_memtype;
+ op.u.del_memtype.handle = 0;
+ op.u.del_memtype.reg = replace_reg;
+
+ error = HYPERVISOR_dom0_op(&op);
+ if (error) {
+ BUG_ON(error > 0);
+ return error;
+ }
+
+ return replace_reg;
+}
+
/* DOM0 TODO: Need to fill in the remaining mtrr methods to have full
* working userland mtrr support. */
static struct mtrr_ops xen_mtrr_ops = {
.vendor = X86_VENDOR_UNKNOWN,
// .set = xen_set_mtrr,
// .get = xen_get_mtrr,
- .get_free_region = generic_get_free_region,
+ .get_free_region = xen_get_free_region,
.validate_add_page = generic_validate_add_page,
.have_wrcomb = positive_have_wrcomb,
};
--
1.5.4.1
linux-2.6-0019-xen-mtrr-Add-xen_-get-set-_mtrr-implementations.patch:
--- NEW FILE linux-2.6-0019-xen-mtrr-Add-xen_-get-set-_mtrr-implementations.patch ---
>From bad9371466c166f7339a6813ecc9a4619fe720ea Mon Sep 17 00:00:00 2001
From: Mark McLoughlin <markmc redhat com>
Date: Tue, 29 Jan 2008 18:29:46 +0000
Subject: [PATCH] xen mtrr: Add xen_{get,set}_mtrr() implementations
Straightforward apart from the hack to turn mtrr_ops->set()
into a no-op on all but one CPU.
Signed-off-by: Mark McLoughlin <markmc redhat com>
---
arch/x86/kernel/cpu/mtrr/xen.c | 52 ++++++++++++++++++++++++++++++++++++---
1 files changed, 48 insertions(+), 4 deletions(-)
diff --git a/arch/x86/kernel/cpu/mtrr/xen.c b/arch/x86/kernel/cpu/mtrr/xen.c
index 6998e00..35b1246 100644
--- a/arch/x86/kernel/cpu/mtrr/xen.c
+++ b/arch/x86/kernel/cpu/mtrr/xen.c
@@ -7,6 +7,52 @@
#include <asm/xen/hypervisor.h>
#include <asm/xen/hypercall.h>
+static void xen_set_mtrr(unsigned int reg, unsigned long base,
+ unsigned long size, mtrr_type type)
+{
+ struct xen_platform_op op;
+ int error;
+
+ /* mtrr_ops->set() is called once per CPU,
+ * but Xen's ops apply to all CPUs.
+ */
+ if (smp_processor_id())
+ return;
+
+ if (size == 0) {
+ op.cmd = XENPF_del_memtype;
+ op.u.del_memtype.handle = 0;
+ op.u.del_memtype.reg = reg;
+ } else {
+ op.cmd = XENPF_add_memtype;
+ op.u.add_memtype.mfn = base;
+ op.u.add_memtype.nr_mfns = size;
+ op.u.add_memtype.type = type;
+ }
+
+ error = HYPERVISOR_dom0_op(&op);
+ BUG_ON(error != 0);
+}
+
+static void xen_get_mtrr(unsigned int reg, unsigned long *base,
+ unsigned long *size, mtrr_type *type)
+{
+ struct xen_platform_op op;
+
+ op.cmd = XENPF_read_memtype;
+ op.u.read_memtype.reg = reg;
+ if (HYPERVISOR_dom0_op(&op) != 0) {
+ *base = 0;
+ *size = 0;
+ *type = 0;
+ return;
+ }
+
+ *size = op.u.read_memtype.nr_mfns;
+ *base = op.u.read_memtype.mfn;
+ *type = op.u.read_memtype.type;
+}
+
static int xen_get_free_region(unsigned long base, unsigned long size, int replace_reg)
{
struct xen_platform_op op;
@@ -32,12 +78,10 @@ static int xen_get_free_region(unsigned long base, unsigned long size, int repla
return replace_reg;
}
-/* DOM0 TODO: Need to fill in the remaining mtrr methods to have full
- * working userland mtrr support. */
static struct mtrr_ops xen_mtrr_ops = {
.vendor = X86_VENDOR_UNKNOWN,
-// .set = xen_set_mtrr,
-// .get = xen_get_mtrr,
+ .set = xen_set_mtrr,
+ .get = xen_get_mtrr,
.get_free_region = xen_get_free_region,
.validate_add_page = generic_validate_add_page,
.have_wrcomb = positive_have_wrcomb,
--
1.5.4.1
linux-2.6-0020-irq2.diff-from-Juan-Quintela.patch:
--- NEW FILE linux-2.6-0020-irq2.diff-from-Juan-Quintela.patch ---
>From 53cb817e322173d6936f92cef04752792e87d7b6 Mon Sep 17 00:00:00 2001
From: Stephen Tweedie <sct redhat com>
Date: Thu, 13 Dec 2007 17:55:34 +0000
Subject: [PATCH] irq2.diff from Juan Quintela.
Some verbose tracing removed.
Signed-off-by: Stephen Tweedie <sct redhat com>
---
arch/x86/kernel/acpi/boot.c | 77 ++++++++---
arch/x86/kernel/apic_32.c | 11 ++
arch/x86/kernel/io_apic_32.c | 100 +++++++++++---
arch/x86/kernel/mpparse_32.c | 15 ++-
arch/x86/kernel/setup_32.c | 17 ++-
arch/x86/kernel/traps_32.c | 41 +++++-
arch/x86/xen/enlighten.c | 2 +-
arch/x86/xen/events.c | 157 ++++++++++++++++++++-
drivers/acpi/tables.c | 14 ++-
include/asm-x86/mach-default/irq_vectors_limits.h | 13 ++
init/main.c | 30 ++++-
11 files changed, 426 insertions(+), 51 deletions(-)
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index e59bda5..6fdda10 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -41,6 +41,7 @@
#include <asm/mpspec.h>
#include <asm/xen/hypervisor.h>
+#include <xen/hvc-console.h>
static int __initdata acpi_force = 0;
@@ -301,16 +302,17 @@ acpi_parse_ioapic(struct acpi_subtable_header * header, const unsigned long end)
{
struct acpi_madt_io_apic *ioapic = NULL;
+ xprintk("ap_ioapic 1\n");
ioapic = (struct acpi_madt_io_apic *)header;
-
+ xprintk("ap_ioapic 2\n");
if (BAD_MADT_ENTRY(ioapic, end))
return -EINVAL;
-
+ xprintk("ap_ioapic 3\n");
acpi_table_print_madt_entry(header);
-
+ xprintk("ap_ioapic 4\n");
mp_register_ioapic(ioapic->id,
ioapic->address, ioapic->global_irq_base);
-
+ xprintk("ap_ioapic 5\n");
return 0;
}
@@ -588,7 +590,13 @@ acpi_scan_rsdp(unsigned long start, unsigned long length)
* RSDP signature.
*/
for (offset = 0; offset < length; offset += 16) {
+#ifdef CONFIG_XEN
+ unsigned long vstart = (unsigned long)isa_bus_to_virt(start);
+
+ if (strncmp((char *)(vstart + offset), "RSD PTR ", sig_len))
+#else
if (strncmp((char *)(phys_to_virt(start) + offset), "RSD PTR ", sig_len))
+#endif
continue;
return (start + offset);
}
@@ -711,7 +719,7 @@ late_initcall(hpet_insert_resource);
static int __init acpi_parse_fadt(struct acpi_table_header *table)
{
-#ifdef CONFIG_X86_PM_TIMER
+#if 0
/* detect the location of the ACPI PM Timer */
if (acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID) {
/* FADT rev. 2 */
@@ -819,6 +827,7 @@ static int __init acpi_parse_madt_ioapic_entries(void)
{
int count;
+ xprintk("apm_ioapic_entries 1\n");
/*
* ACPI interpreter is required to complete interrupt setup,
* so if it is off, don't enumerate the io-apics with ACPI.
@@ -828,59 +837,67 @@ static int __init acpi_parse_madt_ioapic_entries(void)
if (acpi_disabled || acpi_noirq) {
return -ENODEV;
}
-
+ xprintk("apm_ioapic_entries 2\n");
if (!cpu_has_apic)
return -ENODEV;
-
+ xprintk("apm_ioapic_entries 3\n");
/*
* if "noapic" boot option, don't look for IO-APICs
*/
if (skip_ioapic_setup) {
+ xprintk("apm_ioapic_entries 4\n");
printk(KERN_INFO PREFIX "Skipping IOAPIC probe "
"due to 'noapic' option.\n");
return -ENODEV;
}
-
+ xprintk("apm_ioapic_entries 5\n");
count =
acpi_table_parse_madt(ACPI_MADT_TYPE_IO_APIC, acpi_parse_ioapic,
MAX_IO_APICS);
+ xprintk("apm_ioapic_entries 6\n");
if (!count) {
+ xprintk("apm_ioapic_entries 7\n");
printk(KERN_ERR PREFIX "No IOAPIC entries present\n");
return -ENODEV;
} else if (count < 0) {
+ xprintk("apm_ioapic_entries 8\n");
printk(KERN_ERR PREFIX "Error parsing IOAPIC entry\n");
return count;
}
-
+ xprintk("apm_ioapic_entries 9\n");
count =
acpi_table_parse_madt(ACPI_MADT_TYPE_INTERRUPT_OVERRIDE, acpi_parse_int_src_ovr,
NR_IRQ_VECTORS);
+ xprintk("apm_ioapic_entries 10\n");
if (count < 0) {
+ xprintk("apm_ioapic_entries 11\n");
printk(KERN_ERR PREFIX
"Error parsing interrupt source overrides entry\n");
/* TBD: Cleanup to allow fallback to MPS */
return count;
}
-
+ xprintk("apm_ioapic_entries 12\n");
/*
* If BIOS did not supply an INT_SRC_OVR for the SCI
* pretend we got one so we can set the SCI flags.
*/
if (!acpi_sci_override_gsi)
acpi_sci_ioapic_setup(acpi_gbl_FADT.sci_interrupt, 0, 0);
-
+ xprintk("apm_ioapic_entries 13\n");
/* Fill in identity legacy mapings where no override */
mp_config_acpi_legacy_irqs();
-
+ xprintk("apm_ioapic_entries 14\n");
count =
acpi_table_parse_madt(ACPI_MADT_TYPE_NMI_SOURCE, acpi_parse_nmi_src,
NR_IRQ_VECTORS);
+ xprintk("apm_ioapic_entries 15\n");
if (count < 0) {
+ xprintk("apm_ioapic_entries 16\n");
printk(KERN_ERR PREFIX "Error parsing NMI SRC entry\n");
/* TBD: Cleanup to allow fallback to MPS */
return count;
}
-
+ xprintk("apm_ioapic_entries 17\n");
return 0;
}
#else
@@ -895,38 +912,50 @@ static void __init acpi_process_madt(void)
#ifdef CONFIG_X86_LOCAL_APIC
int error;
+ xprintk("acpi_process_madt 1\n");
if (!acpi_table_parse(ACPI_SIG_MADT, acpi_parse_madt)) {
-
+ xprintk("acpi_process_madt 2\n");
/*
* Parse MADT LAPIC entries
*/
error = acpi_parse_madt_lapic_entries();
+ xprintk("acpi_process_madt 3\n");
if (!error) {
+ xprintk("acpi_process_madt 4\n");
acpi_lapic = 1;
#ifdef CONFIG_X86_GENERICARCH
generic_bigsmp_probe();
+ xprintk("acpi_process_madt 5\n");
#endif
/*
* Parse MADT IO-APIC entries
*/
error = acpi_parse_madt_ioapic_entries();
+ xprintk("acpi_process_madt 6\n");
if (!error) {
+ xprintk("acpi_process_madt 7\n");
acpi_irq_model = ACPI_IRQ_MODEL_IOAPIC;
acpi_irq_balance_set(NULL);
+ xprintk("acpi_process_madt 8\n");
acpi_ioapic = 1;
smp_found_config = 1;
setup_apic_routing();
+ xprintk("acpi_process_madt 9\n");
}
+ xprintk("acpi_process_madt 10\n");
}
+ xprintk("acpi_process_madt 11\n");
if (error == -EINVAL) {
+ xprintk("acpi_process_madt 12\n");
/*
* Dell Precision Workstation 410, 610 come here.
*/
printk(KERN_ERR PREFIX
"Invalid BIOS MADT, disabling ACPI\n");
disable_acpi();
+ xprintk("acpi_process_madt 13\n");
}
}
#endif
@@ -1183,6 +1212,7 @@ int __init acpi_boot_table_init(void)
{
int error;
+ xprintk("acpi_boot_table_init 1\n");
#ifdef __i386__
dmi_check_system(acpi_dmi_table);
#endif
@@ -1193,23 +1223,32 @@ int __init acpi_boot_table_init(void)
*/
if (acpi_disabled && !acpi_ht)
return 1;
+ xprintk("acpi_boot_table_init 2\n");
/*
* Initialize the ACPI boot-time table parser.
*/
error = acpi_table_init();
+ xprintk("acpi_boot_table_init 3\n");
if (error) {
+ xprintk("acpi_boot_table_init 4\n");
disable_acpi();
return error;
}
acpi_table_parse(ACPI_SIG_BOOT, acpi_parse_sbf);
+ xprintk("acpi_boot_table_init 5\n");
/*
* blacklist may disable ACPI entirely
*/
+ xprintk("acpi_boot_table_init 6\n");
error = acpi_blacklisted();
+ xprintk("acpi_boot_table_init 7\n");
+
if (error) {
+ xprintk("acpi_boot_table_init 8\n");
+
if (acpi_force) {
printk(KERN_WARNING PREFIX "acpi=force override\n");
} else {
@@ -1218,6 +1257,7 @@ int __init acpi_boot_table_init(void)
return error;
}
}
+ xprintk("acpi_boot_table_init 9\n");
return 0;
}
@@ -1228,22 +1268,25 @@ int __init acpi_boot_init(void)
* If acpi_disabled, bail out
* One exception: acpi=ht continues far enough to enumerate LAPICs
*/
+ xprintk("acpi_boot_init 1\n");
if (acpi_disabled && !acpi_ht)
return 1;
-
+ xprintk("acpi_boot_init 2\n");
acpi_table_parse(ACPI_SIG_BOOT, acpi_parse_sbf);
/*
* set sci_int and PM timer address
*/
+ xprintk("acpi_boot_init 3\n");
acpi_table_parse(ACPI_SIG_FADT, acpi_parse_fadt);
-
/*
* Process the Multiple APIC Description Table (MADT), if present
*/
+ xprintk("acpi_boot_init 4\n");
acpi_process_madt();
-
+ xprintk("acpi_boot_init 5\n");
acpi_table_parse(ACPI_SIG_HPET, acpi_parse_hpet);
+ xprintk("acpi_boot_init 6\n");
return 0;
}
diff --git a/arch/x86/kernel/apic_32.c b/arch/x86/kernel/apic_32.c
index edb5108..06b8860 100644
--- a/arch/x86/kernel/apic_32.c
+++ b/arch/x86/kernel/apic_32.c
@@ -45,6 +45,8 @@
#include "io_ports.h"
+#include <asm/xen/hypervisor.h>
+
/*
* Sanity check
*/
@@ -122,11 +124,15 @@ static inline int lapic_is_integrated(void)
*/
static int modern_apic(void)
{
+#ifndef CONFIG_XEN
/* AMD systems use old APIC versions, so check the CPU */
if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD &&
boot_cpu_data.x86 >= 0xf)
return 1;
return lapic_get_version() >= 0x14;
+#else
+ return 1;
+#endif
}
void apic_wait_icr_idle(void)
@@ -1166,6 +1172,7 @@ fake_ioapic_page:
*/
int __init APIC_init_uniprocessor (void)
{
+#ifndef CONFIG_XEN
if (enable_local_apic < 0)
clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability);
@@ -1198,13 +1205,16 @@ int __init APIC_init_uniprocessor (void)
phys_cpu_present_map = physid_mask_of_physid(boot_cpu_physical_apicid);
setup_local_APIC();
+#endif
#ifdef CONFIG_X86_IO_APIC
if (smp_found_config)
if (!skip_ioapic_setup && nr_ioapics)
setup_IO_APIC();
#endif
+#ifndef CONFIG_XEN
setup_boot_clock();
+#endif
return 0;
}
@@ -1565,3 +1575,4 @@ device_initcall(init_lapic_sysfs);
static void apic_pm_activate(void) { }
#endif /* CONFIG_PM */
+
diff --git a/arch/x86/kernel/io_apic_32.c b/arch/x86/kernel/io_apic_32.c
index a6b1490..fc24cdf 100644
--- a/arch/x86/kernel/io_apic_32.c
+++ b/arch/x86/kernel/io_apic_32.c
@@ -50,6 +50,43 @@
#include "io_ports.h"
+#include <xen/interface/xen.h>
+#include <xen/interface/physdev.h>
+#include <asm/xen/hypercall.h>
+#include <asm/xen/hypervisor.h>
+
+/* Fake i8259 */
+#define make_8259A_irq(_irq) (io_apic_irqs &= ~(1UL<<(_irq)))
+#define disable_8259A_irq(_irq) ((void)0)
+#define i8259A_irq_pending(_irq) (0)
+
+static inline unsigned int xen_io_apic_read(unsigned int apic, unsigned int reg)
+{
+ struct physdev_apic apic_op;
+ int ret;
+
+ apic_op.apic_physbase = mp_ioapics[apic].mpc_apicaddr;
+ apic_op.reg = reg;
+ ret = HYPERVISOR_physdev_op(PHYSDEVOP_apic_read, &apic_op);
+ if (ret)
+ return ret;
+ return apic_op.value;
+}
+
+static inline void xen_io_apic_write(unsigned int apic, unsigned int reg, unsigned int value)
+{
+ struct physdev_apic apic_op;
+
+ apic_op.apic_physbase = mp_ioapics[apic].mpc_apicaddr;
+ apic_op.reg = reg;
+ apic_op.value = value;
+ HYPERVISOR_physdev_op(PHYSDEVOP_apic_write, &apic_op);
+}
+
+#define io_apic_read(a,r) xen_io_apic_read(a,r)
+#define io_apic_write(a,r,v) xen_io_apic_write(a,r,v)
+#define io_apic_modify(a,r,v) xen_io_apic_write(a,r,v)
+
int (*ioapic_renumber_irq)(int ioapic, int irq);
atomic_t irq_mis_count;
@@ -92,6 +129,7 @@ static struct irq_pin_list {
int apic, pin, next;
} irq_2_pin[PIN_MAP_SIZE];
+#ifndef CONFIG_XEN
struct io_apic {
unsigned int index;
unsigned int unused[3];
@@ -131,6 +169,7 @@ static inline void io_apic_modify(unsigned int apic, unsigned int reg, unsigned
writel(reg, &io_apic->index);
writel(value, &io_apic->data);
}
+#endif /* CONFIG_XEN */
union entry_union {
struct { u32 w1, w2; };
@@ -306,6 +345,9 @@ static void clear_IO_APIC_pin(unsigned int apic, unsigned int pin)
ioapic_mask_entry(apic, pin);
}
+#ifdef CONFIG_XEN
+#define clear_IO_APIC() ((void)0)
+#else
static void clear_IO_APIC (void)
{
int apic, pin;
@@ -314,6 +356,7 @@ static void clear_IO_APIC (void)
for (pin = 0; pin < nr_ioapic_registers[apic]; pin++)
clear_IO_APIC_pin(apic, pin);
}
+#endif
#ifdef CONFIG_SMP
static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t cpumask)
@@ -729,6 +772,7 @@ late_initcall(balanced_irq_init);
#ifndef CONFIG_SMP
void fastcall send_IPI_self(int vector)
{
+#ifndef CONFIG_XEN
unsigned int cfg;
/*
@@ -740,6 +784,7 @@ void fastcall send_IPI_self(int vector)
* Send the IPI. The write to APIC_ICR fires this off.
*/
apic_write_around(APIC_ICR, cfg);
+#endif
}
#endif /* !CONFIG_SMP */
@@ -1197,29 +1242,19 @@ static u8 irq_vector[NR_IRQ_VECTORS] __read_mostly = { FIRST_DEVICE_VECTOR , 0 }
static int __assign_irq_vector(int irq)
{
- static int current_vector = FIRST_DEVICE_VECTOR, current_offset = 0;
- int vector, offset;
+ int vector;
+ struct physdev_irq irq_op;
BUG_ON((unsigned)irq >= NR_IRQ_VECTORS);
if (irq_vector[irq] > 0)
return irq_vector[irq];
- vector = current_vector;
- offset = current_offset;
-next:
- vector += 8;
- if (vector >= FIRST_SYSTEM_VECTOR) {
- offset = (offset + 1) % 8;
- vector = FIRST_DEVICE_VECTOR + offset;
- }
- if (vector == current_vector)
+ irq_op.irq = irq;
+ if (HYPERVISOR_physdev_op(PHYSDEVOP_alloc_irq_vector, &irq_op))
return -ENOSPC;
- if (test_and_set_bit(vector, used_vectors))
- goto next;
- current_vector = vector;
- current_offset = offset;
+ vector = irq_op.vector;
irq_vector[irq] = vector;
return vector;
@@ -1236,12 +1271,17 @@ static int assign_irq_vector(int irq)
return vector;
}
+
+
static struct irq_chip ioapic_chip;
#define IOAPIC_AUTO -1
#define IOAPIC_EDGE 0
#define IOAPIC_LEVEL 1
+#ifdef CONFIG_XEN
+#define ioapic_register_intr(_irq,_vector,_trigger) ((void)0)
+#else
static void ioapic_register_intr(int irq, int vector, unsigned long trigger)
{
if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) ||
@@ -1256,6 +1296,7 @@ static void ioapic_register_intr(int irq, int vector, unsigned long trigger)
}
set_intr_gate(vector, interrupt[irq]);
}
+#endif
static void __init setup_IO_APIC_irqs(void)
{
@@ -1316,7 +1357,7 @@ static void __init setup_IO_APIC_irqs(void)
else
add_pin_to_irq(irq, apic, pin);
- if (!apic && !IO_APIC_IRQ(irq))
+ if (/* !apic &&*/ !IO_APIC_IRQ(irq))
continue;
if (IO_APIC_IRQ(irq)) {
@@ -1378,6 +1419,9 @@ static void __init setup_ExtINT_IRQ0_pin(unsigned int apic, unsigned int pin, in
enable_8259A_irq(0);
}
+#ifdef CONFIG_XEN
+void __init print_IO_APIC(void) { }
+#else
void __init print_IO_APIC(void)
{
int apic, i;
@@ -1492,6 +1536,7 @@ void __init print_IO_APIC(void)
return;
}
+#endif /* !CONFIG_XEN */
#if 0
@@ -1717,6 +1762,7 @@ void disable_IO_APIC(void)
*/
clear_IO_APIC();
+#ifndef CONFIG_XEN
/*
* If the i8259 is routed through an IOAPIC
* Put that IOAPIC in virtual wire mode
@@ -1743,6 +1789,7 @@ void disable_IO_APIC(void)
ioapic_write_entry(ioapic_i8259.apic, ioapic_i8259.pin, entry);
}
disconnect_bsp_APIC(ioapic_i8259.pin != -1);
+#endif
}
/*
@@ -1752,7 +1799,7 @@ void disable_IO_APIC(void)
* by Matt Domsch <Matt_Domsch dell com> Tue Dec 21 12:25:05 CST 1999
*/
-#ifndef CONFIG_X86_NUMAQ
+#if !defined(CONFIG_XEN) && !defined(CONFIG_X86_NUMAQ)
static void __init setup_ioapic_ids_from_mpc(void)
{
union IO_APIC_reg_00 reg_00;
@@ -2015,7 +2062,6 @@ static struct irq_chip ioapic_chip __read_mostly = {
.retrigger = ioapic_retrigger_irq,
};
-
static inline void init_IO_APIC_traps(void)
{
int irq;
@@ -2041,9 +2087,11 @@ static inline void init_IO_APIC_traps(void)
*/
if (irq < 16)
make_8259A_irq(irq);
+#ifndef CONFIG_XEN
else
/* Strange. Oh, well.. */
irq_desc[irq].chip = &no_irq_chip;
+#endif
}
}
}
@@ -2159,6 +2207,7 @@ static inline void unlock_ExtINT_logic(void)
int timer_uses_ioapic_pin_0;
+#ifndef CONFIG_XEN
/*
* This code may look a bit paranoid, but it's supposed to cooperate with
* a wide range of boards and BIOS bugs. Fortunately only the timer IRQ
@@ -2288,6 +2337,9 @@ static inline void __init check_timer(void)
out:
local_irq_restore(flags);
}
+#else
+#define check_timer() ((void)0)
+#endif /* CONFIG_XEN */
/*
*
@@ -2320,7 +2372,9 @@ void __init setup_IO_APIC(void)
*/
if (!acpi_ioapic)
setup_ioapic_ids_from_mpc();
+#ifndef CONFIG_XEN
sync_Arb_IDs();
+#endif
setup_IO_APIC_irqs();
init_IO_APIC_traps();
check_timer();
@@ -2351,6 +2405,12 @@ static int __init io_apic_bug_finalize(void)
{
if(sis_apic_bug == -1)
sis_apic_bug = 0;
+ if (is_initial_xendomain()) {
+ struct xen_platform_op op = { .cmd = XENPF_platform_quirk };
+ op.u.platform_quirk.quirk_id = sis_apic_bug ?
+ QUIRK_IOAPIC_BAD_REGSEL : QUIRK_IOAPIC_GOOD_REGSEL;
+ HYPERVISOR_dom0_op(&op);
+ }
return 0;
}
@@ -2465,7 +2525,9 @@ int create_irq(void)
spin_unlock_irqrestore(&vector_lock, flags);
if (irq >= 0) {
+#ifndef CONFIG_XEN
set_intr_gate(vector, interrupt[irq]);
+#endif
dynamic_irq_init(irq);
}
return irq;
@@ -2688,6 +2750,7 @@ int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev)
int __init io_apic_get_unique_id (int ioapic, int apic_id)
{
+#ifndef CONFIG_XEN
union IO_APIC_reg_00 reg_00;
static physid_mask_t apic_id_map = PHYSID_MASK_NONE;
physid_mask_t tmp;
@@ -2756,6 +2819,7 @@ int __init io_apic_get_unique_id (int ioapic, int apic_id)
apic_printk(APIC_VERBOSE, KERN_INFO
"IOAPIC[%d]: Assigned apic_id %d\n", ioapic, apic_id);
+#endif
return apic_id;
}
diff --git a/arch/x86/kernel/mpparse_32.c b/arch/x86/kernel/mpparse_32.c
index 7a05a7f..289041d 100644
--- a/arch/x86/kernel/mpparse_32.c
+++ b/arch/x86/kernel/mpparse_32.c
@@ -105,6 +105,7 @@ static struct mpc_config_translation *translation_table[MAX_MPC_ENTRY] __cpuinit
static void __cpuinit MP_processor_info (struct mpc_config_processor *m)
{
+#ifndef CONFIG_XEN
int ver, apicid;
physid_mask_t phys_cpu;
@@ -195,6 +196,7 @@ static void __cpuinit MP_processor_info (struct mpc_config_processor *m)
}
cpu_set(num_processors, cpu_possible_map);
+#endif
num_processors++;
/*
@@ -204,6 +206,7 @@ static void __cpuinit MP_processor_info (struct mpc_config_processor *m)
* if (CPU_HOTPLUG_ENABLED || num_processors > 8)
* - Ashok Raj <ashok raj intel com>
*/
+#ifndef CONFIG_XEN
if (num_processors > 8) {
switch (boot_cpu_data.x86_vendor) {
case X86_VENDOR_INTEL:
@@ -217,6 +220,7 @@ static void __cpuinit MP_processor_info (struct mpc_config_processor *m)
}
}
bios_cpu_apicid[num_processors - 1] = m->mpc_apicid;
+#endif
}
static void __init MP_bus_info (struct mpc_config_bus *m)
@@ -683,7 +687,11 @@ void __init get_smp_config (void)
* Read the physical hardware table. Anything here will
* override the defaults.
*/
+#ifdef CONFIG_XEN
+ if (!smp_read_mpc(isa_bus_to_virt(mpf->mpf_physptr))) {
+#else
if (!smp_read_mpc(phys_to_virt(mpf->mpf_physptr))) {
+#endif
smp_found_config = 0;
printk(KERN_ERR "BIOS bug, MP table errors detected!...\n");
printk(KERN_ERR "... disabling SMP support. (tell your hw vendor)\n");
@@ -811,6 +819,7 @@ int es7000_plat;
void __init mp_register_lapic_address(u64 address)
{
+#ifndef CONFIG_XEN
mp_lapic_addr = (unsigned long) address;
set_fixmap_nocache(FIX_APIC_BASE, mp_lapic_addr);
@@ -819,6 +828,7 @@ void __init mp_register_lapic_address(u64 address)
boot_cpu_physical_apicid = GET_APIC_ID(apic_read(APIC_ID));
Dprintk("Boot CPU = %d\n", boot_cpu_physical_apicid);
+#endif
}
void __cpuinit mp_register_lapic (u8 id, u8 enabled)
@@ -835,6 +845,7 @@ void __cpuinit mp_register_lapic (u8 id, u8 enabled)
if (id == boot_cpu_physical_apicid)
boot_cpu = 1;
+#ifndef CONFIG_XEN
processor.mpc_type = MP_PROCESSOR;
processor.mpc_apicid = id;
processor.mpc_apicver = GET_APIC_VERSION(apic_read(APIC_LVR));
@@ -845,7 +856,7 @@ void __cpuinit mp_register_lapic (u8 id, u8 enabled)
processor.mpc_featureflag = boot_cpu_data.x86_capability[0];
processor.mpc_reserved[0] = 0;
processor.mpc_reserved[1] = 0;
-
+#endif
MP_processor_info(&processor);
}
@@ -899,7 +910,9 @@ void __init mp_register_ioapic(u8 id, u32 address, u32 gsi_base)
mp_ioapics[idx].mpc_flags = MPC_APIC_USABLE;
mp_ioapics[idx].mpc_apicaddr = address;
+#ifndef CONFIG_XEN
set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address);
+#endif
if ((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL)
&& !APIC_XAPIC(apic_version[boot_cpu_physical_apicid]))
tmpid = io_apic_get_unique_id(idx, id);
diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c
index a441deb..5d9edab 100644
--- a/arch/x86/kernel/setup_32.c
+++ b/arch/x86/kernel/setup_32.c
@@ -62,6 +62,8 @@
#include <bios_ebda.h>
#include <asm/cacheflush.h>
+#include <xen/hvc-console.h>
+
/* This value is set up by the early boot code to point to the value
immediately after the boot time page tables. It contains a *physical*
address, and must not be in the .bss segment! */
@@ -546,10 +548,13 @@ void __init setup_arch(char **cmdline_p)
{
unsigned long max_low_pfn;
+ xprintk("setup_arch 1\n");
memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data));
+ xprintk("setup_arch 2\n");
pre_setup_arch_hook();
+ xprintk("setup_arch 3\n");
early_cpu_init();
-
+ xprintk("setup_arch 4\n");
/*
* FIXME: This isn't an official loader_type right
* now but does currently work with elilo.
@@ -564,6 +569,7 @@ void __init setup_arch(char **cmdline_p)
#endif
ROOT_DEV = old_decode_dev(boot_params.hdr.root_dev);
+ xprintk("setup_arch 5\n");
screen_info = boot_params.screen_info;
edid_info = boot_params.edid_info;
apm_info.bios = boot_params.apm_bios_info;
@@ -671,7 +677,7 @@ void __init setup_arch(char **cmdline_p)
#ifdef CONFIG_ACPI
acpi_boot_init();
-
+ xprintk("setup_arch 10\n");
#if defined(CONFIG_SMP) && defined(CONFIG_X86_PC)
if (def_to_bigsmp)
printk(KERN_WARNING "More than 8 CPUs detected and "
@@ -679,14 +685,16 @@ void __init setup_arch(char **cmdline_p)
"CONFIG_X86_GENERICARCH or CONFIG_X86_BIGSMP.\n");
#endif
#endif
+ xprintk("setup_arch 11\n");
#ifdef CONFIG_X86_LOCAL_APIC
if (smp_found_config)
get_smp_config();
#endif
-
+ xprintk("setup_arch 12\n");
e820_register_memory();
+ xprintk("setup_arch 13\n");
e820_mark_nosave_regions();
-
+ xprintk("setup_arch 14\n");
#ifdef CONFIG_VT
#if defined(CONFIG_VGA_CONSOLE)
if (!efi_enabled || (efi_mem_type(0xa0000) != EFI_CONVENTIONAL_MEMORY))
@@ -695,4 +703,5 @@ void __init setup_arch(char **cmdline_p)
conswitchp = &dummy_con;
#endif
#endif
+ xprintk("setup_arch 15\n");
}
diff --git a/arch/x86/kernel/traps_32.c b/arch/x86/kernel/traps_32.c
index 3b0ac7e..05bb721 100644
--- a/arch/x86/kernel/traps_32.c
+++ b/arch/x86/kernel/traps_32.c
@@ -59,6 +59,8 @@
#include <linux/module.h>
+#include <asm/xen/hypercall.h>
+
#include "mach_traps.h"
int panic_on_unrecovered_nmi;
@@ -1232,10 +1234,42 @@ static void __init set_task_gate(unsigned int n, unsigned int gdt_entry)
}
+/*
+ * NB. All these are "trap gates" (i.e. events_mask isn't set) except
+ * for those that specify <dpl>|4 in the second field.
+ */
+static struct trap_info trap_table[] = {
+ { 0, 0, __KERNEL_CS, (unsigned long)divide_error },
+ { 1, 0|4, __KERNEL_CS, (unsigned long)debug },
+ { 3, 3|4, __KERNEL_CS, (unsigned long)int3 },
+ { 4, 3, __KERNEL_CS, (unsigned long)overflow },
+ { 5, 0, __KERNEL_CS, (unsigned long)bounds },
+ { 6, 0, __KERNEL_CS, (unsigned long)invalid_op },
+ { 7, 0|4, __KERNEL_CS, (unsigned long)device_not_available },
+ { 9, 0, __KERNEL_CS, (unsigned long)coprocessor_segment_overrun },
+ { 10, 0, __KERNEL_CS, (unsigned long)invalid_TSS },
+ { 11, 0, __KERNEL_CS, (unsigned long)segment_not_present },
+ { 12, 0, __KERNEL_CS, (unsigned long)stack_segment },
+ { 13, 0, __KERNEL_CS, (unsigned long)general_protection },
+ { 14, 0|4, __KERNEL_CS, (unsigned long)page_fault },
+ { 15, 0, __KERNEL_CS, (unsigned long)invalid_TSS },
+ { 16, 0, __KERNEL_CS, (unsigned long)coprocessor_error },
+ { 17, 0, __KERNEL_CS, (unsigned long)alignment_check },
+#ifdef CONFIG_X86_MCE
+ { 18, 0, __KERNEL_CS, (unsigned long)machine_check },
+#endif
+ { 19, 0, __KERNEL_CS, (unsigned long)simd_coprocessor_error },
+ { SYSCALL_VECTOR, 3, __KERNEL_CS, (unsigned long)system_call },
+ { 0, 0, 0, 0 }
+};
+
void __init trap_init(void)
{
int i;
+#ifdef CONFIG_XEN
+ HYPERVISOR_set_trap_table(trap_table);
+#else
#ifdef CONFIG_EISA
void __iomem *p = ioremap(0x0FFFD9, 4);
if (readl(p) == 'E'+('I'<<8)+('S'<<16)+('A'<<24)) {
@@ -1270,6 +1304,7 @@ void __init trap_init(void)
set_trap_gate(18,&machine_check);
#endif
set_trap_gate(19,&simd_coprocessor_error);
+#endif /* !CONFIG_XEN */
if (cpu_has_fxsr) {
/*
@@ -1293,8 +1328,9 @@ void __init trap_init(void)
printk("done.\n");
}
+#ifndef CONFIG_XEN
set_system_gate(SYSCALL_VECTOR,&system_call);
-
+#endif
/* Reserve all the builtin and the syscall vector. */
for (i = 0; i < FIRST_EXTERNAL_VECTOR; i++)
set_bit(i, used_vectors);
@@ -1304,8 +1340,9 @@ void __init trap_init(void)
* Should be a barrier for any external CPU state.
*/
cpu_init();
-
+#ifndef CONFIG_XEN
trap_init_hook();
+#endif
}
static int __init kstack_setup(char *s)
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index b84f57b..2d438bb 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -184,8 +184,8 @@ static void xen_cpuid(unsigned int *eax, unsigned int *ebx,
* unsupported kernel subsystems as possible.
*/
if (*eax == 1) {
- maskedx = ~(1 << X86_FEATURE_APIC); /* disable local APIC */
if (!is_initial_xendomain())
+ maskedx = ~(1 << X86_FEATURE_APIC); /* disable local APIC */
maskedx &= ~((1 << X86_FEATURE_ACPI) | /* disable ACPI */
(1 << X86_FEATURE_ACC)); /* thermal monitoring */
}
diff --git a/arch/x86/xen/events.c b/arch/x86/xen/events.c
index 2bf9731..88edd7c 100644
--- a/arch/x86/xen/events.c
+++ b/arch/x86/xen/events.c
@@ -82,6 +82,9 @@ static u8 cpu_evtchn[NR_EVENT_CHANNELS];
/* Reference counts for bindings to IRQs. */
static int irq_bindcount[NR_IRQS];
+/* Bitmap indicating which PIRQs require Xen to be notified on unmask. */
+static DECLARE_BITMAP(pirq_needs_eoi, NR_PIRQS);
+
/* Xen will never allocate port zero for any purpose. */
#define VALID_EVTCHN(chn) ((chn) != 0)
@@ -96,6 +99,8 @@ void force_evtchn_callback(void)
}
EXPORT_SYMBOL_GPL(force_evtchn_callback);
+static DEFINE_PER_CPU(unsigned int, upcall_count) = { 0 };
+
static struct irq_chip xen_dynamic_chip;
/* Constructor for packed IRQ information. */
@@ -235,7 +240,7 @@ static int find_unbound_irq(void)
int irq;
/* Only allocate from dynirq range */
- for (irq = 0; irq < NR_IRQS; irq++)
+ for (irq = DYNIRQ_BASE; irq < NR_IRQS; irq++)
if (irq_bindcount[irq] == 0)
break;
@@ -471,9 +476,15 @@ fastcall void xen_evtchn_do_upcall(struct pt_regs *regs)
struct shared_info *s = HYPERVISOR_shared_info;
struct vcpu_info *vcpu_info = __get_cpu_var(xen_vcpu);
unsigned long pending_words;
+ unsigned int count;
+
+ do {
vcpu_info->evtchn_upcall_pending = 0;
+ if (unlikely(per_cpu(upcall_count, cpu)++))
+ return;
+
/* NB. No need for a barrier here -- XCHG is a barrier on x86. */
pending_words = xchg(&vcpu_info->evtchn_pending_sel, 0);
while (pending_words != 0) {
@@ -492,6 +503,10 @@ fastcall void xen_evtchn_do_upcall(struct pt_regs *regs)
}
}
}
+ /* If there were nested callbacks then we have more to do. */
+ count = per_cpu(upcall_count, cpu);
+ per_cpu(upcall_count, cpu) = 0;
+ } while (unlikely(count != 1));
put_cpu();
}
@@ -573,6 +588,132 @@ static struct irq_chip xen_dynamic_chip __read_mostly = {
.retrigger = retrigger_dynirq,
};
+static inline void pirq_unmask_notify(int irq)
+{
+ struct physdev_eoi eoi = { .irq = irq };
+
+ if (unlikely(test_bit(irq, pirq_needs_eoi)))
+ (void)HYPERVISOR_physdev_op(PHYSDEVOP_eoi, &eoi);
+}
+
+static inline void pirq_query_unmask(int irq)
+{
+ struct physdev_irq_status_query irq_status;
+
+ irq_status.irq = irq;
+ (void)HYPERVISOR_physdev_op(PHYSDEVOP_irq_status_query, &irq_status);
+ clear_bit(irq, pirq_needs_eoi);
+ if (irq_status.flags & XENIRQSTAT_needs_eoi)
+ set_bit(irq, pirq_needs_eoi);
+}
+
+/*
+ * On startup, if there is no action associated with the IRQ then we are
+ * probing. In this case we should not share with others as it will confuse us.
+ */
+#define probing_irq(_irq) (irq_desc[(_irq)].action == NULL)
+
+static unsigned int startup_pirq(unsigned int irq)
+{
+ struct evtchn_bind_pirq bind_pirq;
+ int evtchn = evtchn_from_irq(irq);
+
+ if (VALID_EVTCHN(evtchn))
+ goto out;
+
+ bind_pirq.pirq = irq;
+ /* NB. We are happy to share unless we are probing. */
+ bind_pirq.flags = probing_irq(irq) ? 0 : BIND_PIRQ__WILL_SHARE;
+ if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_pirq, &bind_pirq) != 0) {
+ if (!probing_irq(irq))
+ printk(KERN_INFO "Failed to obtain physical IRQ %d\n",
+ irq);
+ return 0;
+ }
+ evtchn = bind_pirq.port;
+
+ pirq_query_unmask(irq);
+
+ evtchn_to_irq[evtchn] = irq;
+ bind_evtchn_to_cpu(evtchn, 0);
+ irq_info[irq] = mk_irq_info(IRQT_PIRQ, irq, evtchn);
+
+ out:
+ unmask_evtchn(evtchn);
+ pirq_unmask_notify(irq);
+
+ return 0;
+}
+
+static void unmask_pirq(unsigned int irq)
+{
+ int evtchn = evtchn_from_irq(irq);
+
+ if (VALID_EVTCHN(evtchn)) {
+ unmask_evtchn(evtchn);
+ pirq_unmask_notify(irq);
+ }
+}
+
+static void mask_pirq(unsigned int irq)
+{
+ int evtchn = evtchn_from_irq(irq);
+
+ if (VALID_EVTCHN(evtchn))
+ mask_evtchn(evtchn);
+}
+
+static void ack_pirq(unsigned int irq)
+{
+ int evtchn = evtchn_from_irq(irq);
+
+ move_native_irq(irq);
+
+ if (VALID_EVTCHN(evtchn)) {
+ mask_evtchn(evtchn);
+ clear_evtchn(evtchn);
+ }
+}
+
+static void eoi_pirq(unsigned int irq)
+{
+ int evtchn = evtchn_from_irq(irq);
+
+ if (VALID_EVTCHN(evtchn) && !(irq_desc[irq].status & IRQ_DISABLED)) {
+ unmask_evtchn(evtchn);
+ pirq_unmask_notify(irq);
+ }
+}
+
+static int retrigger_pirq(unsigned int irq)
+{
+ int evtchn = evtchn_from_irq(irq);
+ int ret = 0;
+
+ if (VALID_EVTCHN(evtchn)) {
+ struct shared_info *s = HYPERVISOR_shared_info;
+ int masked = sync_test_and_set_bit(evtchn, s->evtchn_mask);
+ set_evtchn(evtchn);
+
+ if (!masked)
+ unmask_evtchn(evtchn);
+ ret = 1;
+ }
+
+ return ret;
+}
+
+static struct irq_chip xen_physical_chip __read_mostly = {
+ .name = "xen-phys",
+ .startup = startup_pirq,
+ .mask = mask_pirq,
+ .unmask = unmask_pirq,
+ .ack = ack_pirq,
+ .eoi = eoi_pirq,
+ .set_affinity = set_affinity_irq,
+ .retrigger = retrigger_pirq,
+};
+
void __init xen_init_IRQ(void)
{
int i;
@@ -584,8 +725,20 @@ void __init xen_init_IRQ(void)
mask_evtchn(i);
/* Dynamic IRQ space is currently unbound. Zero the refcnts. */
- for (i = 0; i < NR_IRQS; i++)
+ for (i = 0; i < NR_IRQS; i++) {
irq_bindcount[i] = 0;
+ irq_info[i] = IRQ_UNBOUND;
+ }
+
+ for (i = 0; i < NR_PIRQS; i++) {
+ irq_bindcount[i] = 1;
+ irq_desc[i].status = IRQ_DISABLED;
+ irq_desc[i].action = NULL;
+ irq_desc[i].depth = 1;
+ set_irq_chip_and_handler_name(i, &xen_physical_chip,
+ handle_level_irq, "pirq");
+ }
+
irq_ctx_init(smp_processor_id());
}
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
index c341918..df800bf 100644
--- a/drivers/acpi/tables.c
+++ b/drivers/acpi/tables.c
@@ -33,6 +33,8 @@
#include <linux/acpi.h>
#include <linux/bootmem.h>
+#include <xen/hvc-console.h>
+
#define PREFIX "ACPI: "
#define ACPI_MAX_TABLES 128
@@ -182,19 +184,21 @@ acpi_table_parse_entries(char *id,
unsigned int count = 0;
unsigned long table_end;
+ xprintk("atp_entries 1\n");
+
if (!handler)
return -EINVAL;
-
+ xprintk("atp_entries 2\n");
if (strncmp(id, ACPI_SIG_MADT, 4) == 0)
acpi_get_table(id, acpi_apic_instance, &table_header);
else
acpi_get_table(id, 0, &table_header);
-
+ xprintk("atp_entries 3\n");
if (!table_header) {
printk(KERN_WARNING PREFIX "%4.4s not present\n", id);
return -ENODEV;
}
-
+ xprintk("atp_entries 4\n");
table_end = (unsigned long)table_header + table_header->length;
/* Parse all entries looking for a match. */
@@ -204,6 +208,7 @@ acpi_table_parse_entries(char *id,
while (((unsigned long)entry) + sizeof(struct acpi_subtable_header) <
table_end) {
+ xprintk("atp_entries 5\n");
if (entry->type == entry_id
&& (!max_entries || count++ < max_entries))
if (handler(entry, table_end))
@@ -212,11 +217,12 @@ acpi_table_parse_entries(char *id,
entry = (struct acpi_subtable_header *)
((unsigned long)entry + entry->length);
}
+ xprintk("atp_entries 6\n");
if (max_entries && count > max_entries) {
printk(KERN_WARNING PREFIX "[%4.4s:0x%02x] ignored %i entries of "
"%i found\n", id, entry_id, count - max_entries, count);
}
-
+ xprintk("atp_entries 7\n");
return count;
}
diff --git a/include/asm-x86/mach-default/irq_vectors_limits.h b/include/asm-x86/mach-default/irq_vectors_limits.h
index a90c7a6..eb5e8a0 100644
--- a/include/asm-x86/mach-default/irq_vectors_limits.h
+++ b/include/asm-x86/mach-default/irq_vectors_limits.h
@@ -1,6 +1,18 @@
#ifndef _ASM_IRQ_VECTORS_LIMITS_H
#define _ASM_IRQ_VECTORS_LIMITS_H
+
+#ifdef CONFIG_XEN
+#define PIRQ_BASE 0
+#define NR_PIRQS 256
+
+#define DYNIRQ_BASE (PIRQ_BASE + NR_PIRQS)
+#define NR_DYNIRQS 256
+
+#define NR_IRQS (NR_PIRQS + NR_DYNIRQS)
+#define NR_IRQ_VECTORS NR_IRQS
+
+#else
#if defined(CONFIG_X86_IO_APIC) || defined(CONFIG_PARAVIRT)
#define NR_IRQS 224
# if (224 >= 32 * NR_CPUS)
@@ -12,5 +24,6 @@
#define NR_IRQS 16
#define NR_IRQ_VECTORS NR_IRQS
#endif
+#endif /* CONFIG_XEN */
#endif /* _ASM_IRQ_VECTORS_LIMITS_H */
diff --git a/init/main.c b/init/main.c
index eee7888..24ac4cd 100644
--- a/init/main.c
+++ b/init/main.c
@@ -68,6 +68,8 @@
#include <asm/smp.h>
#endif
+#include <xen/hvc-console.h>
+
/*
* This is one of the first .c files built. Error out early if we have compiler
* trouble.
@@ -551,56 +553,80 @@ asmlinkage void __init start_kernel(void)
printk(KERN_NOTICE);
printk(linux_banner);
setup_arch(&command_line);
+ xprintk("start_kernel 9\n");
setup_command_line(command_line);
+ xprintk("start_kernel 10\n");
unwind_setup();
+ xprintk("start_kernel 11\n");
setup_per_cpu_areas();
+ xprintk("start_kernel 12\n");
smp_prepare_boot_cpu(); /* arch-specific boot-cpu hooks */
-
+ xprintk("start_kernel 13\n");
/*
* Set up the scheduler prior starting any interrupts (such as the
* timer interrupt). Full topology setup happens at smp_init()
* time - but meanwhile we still have a functioning scheduler.
*/
+ xprintk("start_kernel 14\n");
sched_init();
/*
* Disable preemption - early bootup scheduling is extremely
* fragile until we cpu_idle() for the first time.
*/
+ xprintk("start_kernel 15\n");
preempt_disable();
+ xprintk("start_kernel 16\n");
build_all_zonelists();
+ xprintk("start_kernel 17\n");
page_alloc_init();
+ xprintk("start_kernel 18\n");
printk(KERN_NOTICE "Kernel command line: %s\n", boot_command_line);
parse_early_param();
+ xprintk("start_kernel 19\n");
parse_args("Booting kernel", static_command_line, __start___param,
__stop___param - __start___param,
&unknown_bootoption);
+ xprintk("start_kernel 20\n");
if (!irqs_disabled()) {
printk(KERN_WARNING "start_kernel(): bug: interrupts were "
"enabled *very* early, fixing it\n");
local_irq_disable();
}
+ xprintk("start_kernel 21\n");
sort_main_extable();
+ xprintk("start_kernel 22\n");
trap_init();
+ xprintk("start_kernel 23\n");
rcu_init();
+ xprintk("start_kernel 24\n");
init_IRQ();
+ xprintk("start_kernel 25\n");
pidhash_init();
+ xprintk("start_kernel 26\n");
init_timers();
+ xprintk("start_kernel 27\n");
hrtimers_init();
+ xprintk("start_kernel 28\n");
softirq_init();
+ xprintk("start_kernel 29\n");
timekeeping_init();
+ xprintk("start_kernel 30\n");
time_init();
profile_init();
+ xprintk("start_kernel 31\n");
if (!irqs_disabled())
printk("start_kernel(): bug: interrupts were enabled early\n");
early_boot_irqs_on();
+ xprintk("start_kernel 32\n");
local_irq_enable();
-
+ xprintk("start_kernel 33\n");
/*
* HACK ALERT! This is early. We're enabling the console before
* we've done PCI setups etc, and console_init() must be aware of
* this. But we do want output early, in case something goes wrong.
*/
console_init();
+ xprintk("start_kernel 34\n");
if (panic_later)
panic(panic_later, panic_param);
--
1.5.4.1
linux-2.6-0021-xen-dom0-Obvious-cpuid-fix-to-domU-handling.patch:
--- NEW FILE linux-2.6-0021-xen-dom0-Obvious-cpuid-fix-to-domU-handling.patch ---
>From fb801e12400762fb8cab80beedaa4be854bf0e96 Mon Sep 17 00:00:00 2001
From: Stephen Tweedie <sct redhat com>
Date: Thu, 13 Dec 2007 18:00:17 +0000
Subject: [PATCH] xen dom0: Obvious cpuid fix to domU handling.
Signed-off-by: Stephen Tweedie <sct redhat com>
---
arch/x86/xen/enlighten.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index 2d438bb..806d739 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -184,10 +184,11 @@ static void xen_cpuid(unsigned int *eax, unsigned int *ebx,
* unsupported kernel subsystems as possible.
*/
if (*eax == 1) {
- if (!is_initial_xendomain())
+ if (!is_initial_xendomain()) {
maskedx = ~(1 << X86_FEATURE_APIC); /* disable local APIC */
maskedx &= ~((1 << X86_FEATURE_ACPI) | /* disable ACPI */
(1 << X86_FEATURE_ACC)); /* thermal monitoring */
+ }
}
asm(XEN_EMULATE_PREFIX "cpuid"
--
1.5.4.1
linux-2.6-0022-xen-debug-Diagnose-bind_virq_to_irq-errors.patch:
--- NEW FILE linux-2.6-0022-xen-debug-Diagnose-bind_virq_to_irq-errors.patch ---
>From 2d1568fdd5f24f8794370e75284903122096ea55 Mon Sep 17 00:00:00 2001
From: Stephen Tweedie <sct redhat com>
Date: Mon, 7 Jan 2008 20:39:20 +0000
Subject: [PATCH] xen debug: Diagnose bind_virq_to_irq errors
Signed-off-by: Stephen Tweedie <sct redhat com>
---
arch/x86/xen/events.c | 5 ++++-
1 files changed, 4 insertions(+), 1 deletions(-)
diff --git a/arch/x86/xen/events.c b/arch/x86/xen/events.c
index 88edd7c..1014809 100644
--- a/arch/x86/xen/events.c
+++ b/arch/x86/xen/events.c
@@ -329,8 +329,11 @@ int bind_virq_to_irq(unsigned int virq, unsigned int cpu)
bind_virq.virq = virq;
bind_virq.vcpu = cpu;
if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_virq,
- &bind_virq) != 0)
+ &bind_virq) != 0) {
+ printk(KERN_ERR "%s: failed on virq %u, vcpu %u\n",
+ __FUNCTION__, virq, cpu);
BUG();
+ }
evtchn = bind_virq.port;
irq = find_unbound_irq();
--
1.5.4.1
linux-2.6-0023-xen-traps-Revert-Juan-s-traps_32.c-changes-to-debug.patch:
--- NEW FILE linux-2.6-0023-xen-traps-Revert-Juan-s-traps_32.c-changes-to-debug.patch ---
>From b017ec4d76818b8336e405bbbac1bc62f2444338 Mon Sep 17 00:00:00 2001
From: Stephen Tweedie <sct redhat com>
Date: Mon, 7 Jan 2008 20:39:51 +0000
Subject: [PATCH] xen traps: Revert Juan's traps_32.c changes to debug why they are needed.
Signed-off-by: Stephen Tweedie <sct redhat com>
---
arch/x86/kernel/traps_32.c | 41 ++---------------------------------------
1 files changed, 2 insertions(+), 39 deletions(-)
diff --git a/arch/x86/kernel/traps_32.c b/arch/x86/kernel/traps_32.c
index 05bb721..3b0ac7e 100644
--- a/arch/x86/kernel/traps_32.c
+++ b/arch/x86/kernel/traps_32.c
@@ -59,8 +59,6 @@
#include <linux/module.h>
-#include <asm/xen/hypercall.h>
-
#include "mach_traps.h"
int panic_on_unrecovered_nmi;
@@ -1234,42 +1232,10 @@ static void __init set_task_gate(unsigned int n, unsigned int gdt_entry)
}
-/*
- * NB. All these are "trap gates" (i.e. events_mask isn't set) except
- * for those that specify <dpl>|4 in the second field.
- */
-static struct trap_info trap_table[] = {
- { 0, 0, __KERNEL_CS, (unsigned long)divide_error },
- { 1, 0|4, __KERNEL_CS, (unsigned long)debug },
- { 3, 3|4, __KERNEL_CS, (unsigned long)int3 },
- { 4, 3, __KERNEL_CS, (unsigned long)overflow },
- { 5, 0, __KERNEL_CS, (unsigned long)bounds },
- { 6, 0, __KERNEL_CS, (unsigned long)invalid_op },
- { 7, 0|4, __KERNEL_CS, (unsigned long)device_not_available },
- { 9, 0, __KERNEL_CS, (unsigned long)coprocessor_segment_overrun },
- { 10, 0, __KERNEL_CS, (unsigned long)invalid_TSS },
- { 11, 0, __KERNEL_CS, (unsigned long)segment_not_present },
- { 12, 0, __KERNEL_CS, (unsigned long)stack_segment },
- { 13, 0, __KERNEL_CS, (unsigned long)general_protection },
- { 14, 0|4, __KERNEL_CS, (unsigned long)page_fault },
- { 15, 0, __KERNEL_CS, (unsigned long)invalid_TSS },
- { 16, 0, __KERNEL_CS, (unsigned long)coprocessor_error },
- { 17, 0, __KERNEL_CS, (unsigned long)alignment_check },
-#ifdef CONFIG_X86_MCE
- { 18, 0, __KERNEL_CS, (unsigned long)machine_check },
-#endif
- { 19, 0, __KERNEL_CS, (unsigned long)simd_coprocessor_error },
- { SYSCALL_VECTOR, 3, __KERNEL_CS, (unsigned long)system_call },
- { 0, 0, 0, 0 }
-};
-
void __init trap_init(void)
{
int i;
-#ifdef CONFIG_XEN
- HYPERVISOR_set_trap_table(trap_table);
-#else
#ifdef CONFIG_EISA
void __iomem *p = ioremap(0x0FFFD9, 4);
if (readl(p) == 'E'+('I'<<8)+('S'<<16)+('A'<<24)) {
@@ -1304,7 +1270,6 @@ void __init trap_init(void)
set_trap_gate(18,&machine_check);
#endif
set_trap_gate(19,&simd_coprocessor_error);
-#endif /* !CONFIG_XEN */
if (cpu_has_fxsr) {
/*
@@ -1328,9 +1293,8 @@ void __init trap_init(void)
printk("done.\n");
}
-#ifndef CONFIG_XEN
set_system_gate(SYSCALL_VECTOR,&system_call);
-#endif
+
/* Reserve all the builtin and the syscall vector. */
for (i = 0; i < FIRST_EXTERNAL_VECTOR; i++)
set_bit(i, used_vectors);
@@ -1340,9 +1304,8 @@ void __init trap_init(void)
* Should be a barrier for any external CPU state.
*/
cpu_init();
-#ifndef CONFIG_XEN
+
trap_init_hook();
-#endif
}
static int __init kstack_setup(char *s)
--
1.5.4.1
linux-2.6-0024-xen-debug-Move-init_apic_mappings-after-trap-init.patch:
--- NEW FILE linux-2.6-0024-xen-debug-Move-init_apic_mappings-after-trap-init.patch ---
>From 5d9910acad1949a7754860667c4c02e786483f0e Mon Sep 17 00:00:00 2001
From: Stephen Tweedie <sct redhat com>
Date: Tue, 8 Jan 2008 15:33:44 +0000
Subject: [PATCH] xen debug: Move init_apic_mappings() after trap initialisation.
Improves the chance of meaningful debug output if the apic init goes wrong.
Signed-off-by: Stephen Tweedie <sct redhat com>
---
arch/x86/kernel/traps_32.c | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/arch/x86/kernel/traps_32.c b/arch/x86/kernel/traps_32.c
index 3b0ac7e..e7c3922 100644
--- a/arch/x86/kernel/traps_32.c
+++ b/arch/x86/kernel/traps_32.c
@@ -1244,10 +1244,6 @@ void __init trap_init(void)
iounmap(p);
#endif
-#ifdef CONFIG_X86_LOCAL_APIC
- init_apic_mappings();
-#endif
-
set_trap_gate(0,÷_error);
set_intr_gate(1,&debug);
set_intr_gate(2,&nmi);
@@ -1271,6 +1267,10 @@ void __init trap_init(void)
#endif
set_trap_gate(19,&simd_coprocessor_error);
+#ifdef CONFIG_X86_LOCAL_APIC
+ init_apic_mappings();
+#endif
+
if (cpu_has_fxsr) {
/*
* Verify that the FXSAVE/FXRSTOR data will be 16-byte aligned.
--
1.5.4.1
linux-2.6-0025-xen-debug-Trace-progress-in-trap_init-around-init.patch:
--- NEW FILE linux-2.6-0025-xen-debug-Trace-progress-in-trap_init-around-init.patch ---
>From 508af97e08ab1aa90cb5a6f1b6396e4cbf3c9c8f Mon Sep 17 00:00:00 2001
From: Stephen Tweedie <sct redhat com>
Date: Tue, 8 Jan 2008 15:54:05 +0000
Subject: [PATCH] xen debug: Trace progress in trap_init() around init_apic_mappings()
Signed-off-by: Stephen Tweedie <sct redhat com>
---
arch/x86/kernel/traps_32.c | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/arch/x86/kernel/traps_32.c b/arch/x86/kernel/traps_32.c
index e7c3922..8f299a8 100644
--- a/arch/x86/kernel/traps_32.c
+++ b/arch/x86/kernel/traps_32.c
@@ -61,6 +61,8 @@
#include "mach_traps.h"
+#include <xen/hvc-console.h>
+
int panic_on_unrecovered_nmi;
DECLARE_BITMAP(used_vectors, NR_VECTORS);
@@ -1244,6 +1246,7 @@ void __init trap_init(void)
iounmap(p);
#endif
+ xprintk("trap_init 0\n");
set_trap_gate(0,÷_error);
set_intr_gate(1,&debug);
set_intr_gate(2,&nmi);
@@ -1268,7 +1271,9 @@ void __init trap_init(void)
set_trap_gate(19,&simd_coprocessor_error);
#ifdef CONFIG_X86_LOCAL_APIC
+ xprintk("trap_init 1\n");
init_apic_mappings();
+ xprintk("trap_init 2\n");
#endif
if (cpu_has_fxsr) {
--
1.5.4.1
linux-2.6-0026-xen-apic-Disable-init_apic_mappings-when-under-CO.patch:
--- NEW FILE linux-2.6-0026-xen-apic-Disable-init_apic_mappings-when-under-CO.patch ---
>From 99c0cd927046606f7d078038525d787442f31643 Mon Sep 17 00:00:00 2001
From: Stephen Tweedie <sct redhat com>
Date: Tue, 8 Jan 2008 15:54:38 +0000
Subject: [PATCH] xen apic: Disable init_apic_mappings() when under CONFIG_XEN
Hack, needs to be a runtime switch.
Signed-off-by: Stephen Tweedie <sct redhat com>
---
arch/x86/kernel/apic_32.c | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/arch/x86/kernel/apic_32.c b/arch/x86/kernel/apic_32.c
index 06b8860..637a735 100644
--- a/arch/x86/kernel/apic_32.c
+++ b/arch/x86/kernel/apic_32.c
@@ -1110,6 +1110,7 @@ no_apic:
*/
void __init init_apic_mappings(void)
{
+#ifndef CONFIG_XEN
unsigned long apic_phys;
/*
@@ -1164,6 +1165,7 @@ fake_ioapic_page:
}
}
#endif
+#endif
}
/*
--
1.5.4.1
linux-2.6-0027-xen-debug-Log-entry-into-virtual-console-s-xen_init.patch:
--- NEW FILE linux-2.6-0027-xen-debug-Log-entry-into-virtual-console-s-xen_init.patch ---
>From 3eebd4611b43778a7a59809cecd8b71c8ba4ab37 Mon Sep 17 00:00:00 2001
From: Stephen Tweedie <sct redhat com>
Date: Tue, 8 Jan 2008 18:42:32 +0000
Subject: [PATCH] xen debug: Log entry into virtual console's xen_init() function
Signed-off-by: Stephen Tweedie <sct redhat com>
---
drivers/char/hvc_xen.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/drivers/char/hvc_xen.c b/drivers/char/hvc_xen.c
index 6e85664..db5bff3 100644
--- a/drivers/char/hvc_xen.c
+++ b/drivers/char/hvc_xen.c
@@ -136,6 +136,9 @@ static int __init xen_init(void)
if (!is_running_on_xen())
return 0;
+ printk(KERN_INFO "%s: entered on cpu %d\n",
+ __FUNCTION__, smp_processor_id());
+
if (is_initial_xendomain()) {
ops = &dom0_hvc_ops;
xencons_irq = bind_virq_to_irq(VIRQ_CONSOLE, 0);
--
1.5.4.1
linux-2.6-0028-xen-debug-Log-bind_virq_to_irq-events.patch:
--- NEW FILE linux-2.6-0028-xen-debug-Log-bind_virq_to_irq-events.patch ---
>From 5a91a9915e7fb65becd43bbeac59d09fc4e523cf Mon Sep 17 00:00:00 2001
From: Stephen Tweedie <sct redhat com>
Date: Tue, 8 Jan 2008 18:43:03 +0000
Subject: [PATCH] xen debug: Log bind_virq_to_irq events
Signed-off-by: Stephen Tweedie <sct redhat com>
---
arch/x86/xen/events.c | 10 +++++-----
1 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/arch/x86/xen/events.c b/arch/x86/xen/events.c
index 1014809..ca4912e 100644
--- a/arch/x86/xen/events.c
+++ b/arch/x86/xen/events.c
@@ -319,7 +319,7 @@ static int bind_ipi_to_irq(unsigned int ipi, unsigned int cpu)
int bind_virq_to_irq(unsigned int virq, unsigned int cpu)
{
struct evtchn_bind_virq bind_virq;
- int evtchn, irq;
+ int evtchn, irq, rc;
spin_lock(&irq_mapping_update_lock);
@@ -328,10 +328,10 @@ int bind_virq_to_irq(unsigned int virq, unsigned int cpu)
if (irq == -1) {
bind_virq.virq = virq;
bind_virq.vcpu = cpu;
- if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_virq,
- &bind_virq) != 0) {
- printk(KERN_ERR "%s: failed on virq %u, vcpu %u\n",
- __FUNCTION__, virq, cpu);
+ if ((rc = HYPERVISOR_event_channel_op(EVTCHNOP_bind_virq,
+ &bind_virq)) != 0) {
+ printk(KERN_ERR "%s: failed on virq %u, vcpu %u, err %d\n",
+ __FUNCTION__, virq, cpu, rc);
BUG();
}
evtchn = bind_virq.port;
--
1.5.4.1
linux-2.6-0029-xen-debug-Work-around-USB-issue-triggered-by-Xen-de.patch:
--- NEW FILE linux-2.6-0029-xen-debug-Work-around-USB-issue-triggered-by-Xen-de.patch ---
>From 44f69ec851da845860369311087433ea6f7f750b Mon Sep 17 00:00:00 2001
From: Stephen Tweedie <sct redhat com>
Date: Mon, 4 Feb 2008 22:10:55 +0000
Subject: [PATCH] xen debug: Work around USB issue triggered by Xen debugging.
It appears that having too much serial console output from Xen's
startup_pirq() is tripping up a race in the usb stack when usb
initialisation fails. By the time usb_kick_khubd gets around to
poking the khubd, the driver has already been torn down, and we
get a null pointer deref.
Checking for that in usb_kick_khubd lets us get past that, but
we still need to work out why the usb init is failing in the
first place.
Signed-off-by: Stephen Tweedie <sct redhat com>
---
drivers/usb/core/hub.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index b04d232..5a335ee 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -345,7 +345,8 @@ static void kick_khubd(struct usb_hub *hub)
void usb_kick_khubd(struct usb_device *hdev)
{
/* FIXME: What if hdev isn't bound to the hub driver? */
- kick_khubd(hdev_to_hub(hdev));
+ if (hdev && hdev->actconfig && hdev_to_hub(hdev))
+ kick_khubd(hdev_to_hub(hdev));
}
--
1.5.4.1
linux-2.6-0030-Remove-duplicated-dma_alloc-free_noncoherent-define.patch:
--- NEW FILE linux-2.6-0030-Remove-duplicated-dma_alloc-free_noncoherent-define.patch ---
>From 986933e6605e1dfbe5b1dfdb1f5f406215efc5cf Mon Sep 17 00:00:00 2001
From: Stephen Tweedie <sct redhat com>
Date: Mon, 21 Jan 2008 16:18:57 +0000
Subject: [PATCH] Remove duplicated dma_alloc/free_noncoherent #defines.
Signed-off-by: Stephen Tweedie <sct redhat com>
---
include/asm-x86/dma-mapping_64.h | 3 ---
1 files changed, 0 insertions(+), 3 deletions(-)
diff --git a/include/asm-x86/dma-mapping_64.h b/include/asm-x86/dma-mapping_64.h
index ecd0f61..d0e10b3 100644
--- a/include/asm-x86/dma-mapping_64.h
+++ b/include/asm-x86/dma-mapping_64.h
@@ -65,9 +65,6 @@ static inline int dma_mapping_error(dma_addr_t dma_addr)
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
-#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
-#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
-
extern void *dma_alloc_coherent(struct device *dev, size_t size,
dma_addr_t *dma_handle, gfp_t gfp);
extern void dma_free_coherent(struct device *dev, size_t size, void *vaddr,
--
1.5.4.1
linux-2.6-0031-xem-dom0-Add-hypervisor-memory_exchange-descriptor.patch:
--- NEW FILE linux-2.6-0031-xem-dom0-Add-hypervisor-memory_exchange-descriptor.patch ---
>From 0ea94cbcfba1217d99582a479b5e1683340f8087 Mon Sep 17 00:00:00 2001
From: Stephen Tweedie <sct redhat com>
Date: Thu, 31 Jan 2008 19:26:06 +0000
Subject: [PATCH] xem dom0: Add hypervisor memory_exchange descriptor
Adds the memory_exchange descriptors needed to allow dom0 to ask
the hypervisor to force regions of its memory to be machine-
contiguous.
Signed-off-by: Stephen Tweedie <sct redhat com>
---
include/xen/interface/memory.h | 42 ++++++++++++++++++++++++++++++++++++++++
1 files changed, 42 insertions(+), 0 deletions(-)
diff --git a/include/xen/interface/memory.h b/include/xen/interface/memory.h
index af36ead..1ad1d74 100644
--- a/include/xen/interface/memory.h
+++ b/include/xen/interface/memory.h
@@ -142,4 +142,46 @@ struct xen_translate_gpfn_list {
};
DEFINE_GUEST_HANDLE_STRUCT(xen_translate_gpfn_list);
+/*
+ * An atomic exchange of memory pages. If return code is zero then
+ * @out.extent_list provides GMFNs of the newly-allocated memory.
+ * Returns zero on complete success, otherwise a negative error code.
+ * On complete success then always @nr_exchanged == @in.nr_extents.
+ * On partial success @nr_exchanged indicates how much work was done.
+ */
+#define XENMEM_exchange 11
+struct xen_memory_exchange {
+ /*
+ * [IN] Details of memory extents to be exchanged (GMFN bases).
+ * Note that @in.address_bits is ignored and unused.
+ */
+ struct xen_memory_reservation in;
+
+ /*
+ * [IN/OUT] Details of new memory extents.
+ * We require that:
+ * 1. @in.domid == @out.domid
+ * 2. @in.nr_extents << @in.extent_order ==
+ * @out.nr_extents << @out.extent_order
+ * 3. @in.extent_start and @out.extent_start lists must not overlap
+ * 4. @out.extent_start lists GPFN bases to be populated
+ * 5. @out.extent_start is overwritten with allocated GMFN bases
+ */
+ struct xen_memory_reservation out;
+
+ /*
+ * [OUT] Number of input extents that were successfully exchanged:
+ * 1. The first @nr_exchanged input extents were successfully
+ * deallocated.
+ * 2. The corresponding first entries in the output extent list correctly
+ * indicate the GMFNs that were successfully exchanged.
+ * 3. All other input and output extents are untouched.
+ * 4. If not all input exents are exchanged then the return code of this
+ * command will be non-zero.
+ * 5. THIS FIELD MUST BE INITIALISED TO ZERO BY THE CALLER!
+ */
+ unsigned int nr_exchanged;
+};
+DEFINE_GUEST_HANDLE_STRUCT(xen_memory_exchange);
+
#endif /* __XEN_PUBLIC_MEMORY_H__ */
--
1.5.4.1
linux-2.6-0032-xen-dom0-add-virt_to_pfn-macro.patch:
--- NEW FILE linux-2.6-0032-xen-dom0-add-virt_to_pfn-macro.patch ---
>From 9c8475bdd4f183f5523c9c023438634cb86df51f Mon Sep 17 00:00:00 2001
From: Stephen Tweedie <sct redhat com>
Date: Mon, 4 Feb 2008 16:40:57 +0000
Subject: [PATCH] xen dom0: add virt_to_pfn() macro
The xen/mmu.c code is computing pfns manually via PFN_DOWN(__pa(v))
in various places. Add a new virt_to_pfn macro to do that more
cleanly, complementing the existing virt_to_mfn in include/xen/page.h.
Signed-off-by: Stephen Tweedie <sct redhat com>
---
include/xen/page.h | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/include/xen/page.h b/include/xen/page.h
index c0c8fcb..ce45a6b 100644
--- a/include/xen/page.h
+++ b/include/xen/page.h
@@ -134,7 +134,8 @@ static inline void set_phys_to_machine(unsigned long pfn, unsigned long mfn)
/* VIRT <-> MACHINE conversion */
#define virt_to_machine(v) (phys_to_machine(XPADDR(__pa(v))))
-#define virt_to_mfn(v) (pfn_to_mfn(PFN_DOWN(__pa(v))))
+#define virt_to_pfn(v) (PFN_DOWN(__pa(v)))
+#define virt_to_mfn(v) (pfn_to_mfn(virt_to_pfn(v)))
#define mfn_to_virt(m) (__va(mfn_to_pfn(m) << PAGE_SHIFT))
#ifdef CONFIG_X86_PAE
--
1.5.4.1
linux-2.6-0033-xen-dom0-use-virt_to_pfn-where-appropriate.patch:
--- NEW FILE linux-2.6-0033-xen-dom0-use-virt_to_pfn-where-appropriate.patch ---
>From 4930263799244e70071eff8810194d26c0bc2e61 Mon Sep 17 00:00:00 2001
From: Stephen Tweedie <sct redhat com>
Date: Mon, 4 Feb 2008 16:42:35 +0000
Subject: [PATCH] xen dom0: use virt_to_pfn() where appropriate
Simply cleans up the code to use avoid manually coding the virt-to-pfn
conversion all over the place.
Signed-off-by: Stephen Tweedie <sct redhat com>
---
arch/x86/xen/mmu.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
index 2e28104..5bbdbb7 100644
--- a/arch/x86/xen/mmu.c
+++ b/arch/x86/xen/mmu.c
@@ -454,7 +454,7 @@ void xen_pgd_pin(pgd_t *pgd)
level = MMUEXT_PIN_L2_TABLE;
#endif
- xen_do_pin(level, PFN_DOWN(__pa(pgd)));
+ xen_do_pin(level, virt_to_pfn(pgd));
xen_mc_issue(0);
}
@@ -509,7 +509,7 @@ static void xen_pgd_unpin(pgd_t *pgd)
{
xen_mc_batch();
- xen_do_pin(MMUEXT_UNPIN_TABLE, PFN_DOWN(__pa(pgd)));
+ xen_do_pin(MMUEXT_UNPIN_TABLE, virt_to_pfn(pgd));
pgd_walk(pgd, unpin_page, TASK_SIZE);
--
1.5.4.1
linux-2.6-0034-xen-dom0-Add-contiguous-region-support.patch:
--- NEW FILE linux-2.6-0034-xen-dom0-Add-contiguous-region-support.patch ---
>From 82e3dab7c67277c9986bd2d1020be5a8a122cedf Mon Sep 17 00:00:00 2001
From: Stephen Tweedie <sct redhat com>
Date: Thu, 31 Jan 2008 11:47:28 +0000
Subject: [PATCH] xen dom0: Add contiguous region support.
Adds xen_(create|destroy)_contiguous_region, to force ranges of pfns
to be physically contiguous in machine ram, so that DMA can be
performed correctly from it.
Based on the code from linux-2.6.18-xen.hg, but updated to use
multicall batching for contig region pte updating, and refactored to
split out the common code for zapping/remapping ptes and performing
the memory exchange hypercall.
Signed-off-by: Stephen Tweedie <sct redhat com>
---
arch/x86/xen/enlighten.c | 21 +++-
arch/x86/xen/mmu.c | 247 +++++++++++++++++++++++++++++++++++++++++++++-
include/xen/page.h | 17 +++
3 files changed, 280 insertions(+), 5 deletions(-)
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index 806d739..a11607a 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -865,18 +865,31 @@ static __init void xen_pagetable_setup_done(pgd_t *base)
pin_pagetable_pfn(level, PFN_DOWN(__pa(base)));
}
- /*
- * If we're dom0, then 1:1 map the ISA machine addresses into
- * the kernel's address space.
- */
if (is_initial_xendomain()) {
unsigned i;
+ extern unsigned long *contiguous_bitmap;
+ /*
+ * If we're dom0, then 1:1 map the ISA machine addresses
+ * into the kernel's address space.
+ */
for(i = ISA_START_ADDRESS; i < ISA_END_ADDRESS; i += PAGE_SIZE)
set_pte_mfn(PAGE_OFFSET + i, PFN_DOWN(i), PAGE_KERNEL);
reserve_bootmem(ISA_START_ADDRESS, ISA_END_ADDRESS - ISA_START_ADDRESS);
printk(KERN_INFO "Xen: setup ISA identity maps\n");
+
+ /*
+ * Allocate a contiguous page bitmap, to mark dma
+ * coherent regions. This may eventually be needed for
+ * domU too, if PCI front/back support is added, but for
+ * now it is only required for dom0.
+ */
+ contiguous_bitmap = alloc_bootmem_low_pages
+ ((max_low_pfn + 2*BITS_PER_LONG) >> 3);
+ BUG_ON(!contiguous_bitmap);
+ memset(contiguous_bitmap, 0, (max_low_pfn + 2*BITS_PER_LONG) >> 3);
+
}
}
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
index 5bbdbb7..54b6275 100644
--- a/arch/x86/xen/mmu.c
+++ b/arch/x86/xen/mmu.c
@@ -47,15 +47,17 @@
#include <asm/mmu_context.h>
#include <asm/paravirt.h>
-#include <asm/xen/hypercall.h>
#include <asm/xen/hypervisor.h>
#include <xen/page.h>
#include <xen/interface/xen.h>
+#include <xen/interface/memory.h>
#include "multicalls.h"
#include "mmu.h"
+DEFINE_SPINLOCK(reservation_lock);
+
xmaddr_t arbitrary_virt_to_machine(unsigned long address)
{
pte_t *pte = lookup_address(address);
@@ -614,3 +616,246 @@ void xen_exit_mmap(struct mm_struct *mm)
spin_unlock(&mm->page_table_lock);
}
+
+
+/*
+ * Bitmap is indexed by page number. If bit is set, the page is part of a
+ * xen_create_contiguous_region() area of memory.
+ */
+unsigned long *contiguous_bitmap;
+
+static void contiguous_bitmap_set(
+ unsigned long first_page, unsigned long nr_pages)
+{
+ unsigned long start_off, end_off, curr_idx, end_idx;
+
+ curr_idx = first_page / BITS_PER_LONG;
+ start_off = first_page & (BITS_PER_LONG-1);
+ end_idx = (first_page + nr_pages) / BITS_PER_LONG;
+ end_off = (first_page + nr_pages) & (BITS_PER_LONG-1);
+
+ if (curr_idx == end_idx) {
+ contiguous_bitmap[curr_idx] |=
+ ((1UL<<end_off)-1) & -(1UL<<start_off);
+ } else {
+ contiguous_bitmap[curr_idx] |= -(1UL<<start_off);
+ while ( ++curr_idx < end_idx )
+ contiguous_bitmap[curr_idx] = ~0UL;
+ contiguous_bitmap[curr_idx] |= (1UL<<end_off)-1;
+ }
+}
+
+static void contiguous_bitmap_clear(
+ unsigned long first_page, unsigned long nr_pages)
+{
+ unsigned long start_off, end_off, curr_idx, end_idx;
+
+ curr_idx = first_page / BITS_PER_LONG;
+ start_off = first_page & (BITS_PER_LONG-1);
+ end_idx = (first_page + nr_pages) / BITS_PER_LONG;
+ end_off = (first_page + nr_pages) & (BITS_PER_LONG-1);
+
+ if (curr_idx == end_idx) {
+ contiguous_bitmap[curr_idx] &=
+ -(1UL<<end_off) | ((1UL<<start_off)-1);
+ } else {
+ contiguous_bitmap[curr_idx] &= (1UL<<start_off)-1;
+ while ( ++curr_idx != end_idx )
+ contiguous_bitmap[curr_idx] = 0;
+ contiguous_bitmap[curr_idx] &= -(1UL<<end_off);
+ }
+}
+
+/* Protected by balloon_lock. */
+#define MAX_CONTIG_ORDER 9 /* 2MB */
+static unsigned long discontig_frames[1<<MAX_CONTIG_ORDER];
+
+/*
+ * Zap a range of ptes, recording the pfn and mfn numbers as required as
+ * we go
+ */
+#define VOID_PTE (mfn_pte(0, __pgprot(0)))
+static void xen_zap_pfn_range(unsigned long vaddr, int order,
+ unsigned long *in_frames,
+ unsigned long *out_frames)
+{
+ int i;
+ struct multicall_space mcs;
+
+ xen_mc_batch();
+ for (i = 0; i < (1UL<<order); i++, vaddr += PAGE_SIZE) {
+ mcs = __xen_mc_entry(0);
+
+ if (in_frames)
+ in_frames[i] = virt_to_mfn(vaddr);
+
+ MULTI_update_va_mapping(mcs.mc, vaddr, VOID_PTE, 0);
+ set_phys_to_machine(virt_to_pfn(vaddr), INVALID_P2M_ENTRY);
+
+ if (out_frames)
+ out_frames[i] = virt_to_pfn(vaddr);
+ }
+ xen_mc_issue(0);
+}
+
+/*
+ * Update the pfn-to-mfn mappings for a virtual address range, either to
+ * point to an array of mfns, or contiguously from a single starting
+ * mfn.
+ */
+static void xen_remap_exchanged_ptes(unsigned long vaddr, int order,
+ unsigned long *mfns,
+ unsigned long first_mfn)
+{
+ int i;
+ unsigned long mfn;
+ struct multicall_space mcs;
+
+ xen_mc_batch();
+ for (i = 0; i < (1UL<<order); i++, vaddr += PAGE_SIZE) {
+ mcs = __xen_mc_entry(0);
+
+ if (mfns)
+ mfn = mfns[i];
+ else
+ mfn = first_mfn + i;
+ MULTI_update_va_mapping(mcs.mc, vaddr,
+ mfn_pte(mfn, PAGE_KERNEL), 0);
+ set_phys_to_machine(virt_to_pfn(vaddr), mfn);
+ }
+
+ mcs.mc->args[MULTI_UVMFLAGS_INDEX] = order ? UVMF_TLB_FLUSH|UVMF_ALL
+ : UVMF_INVLPG|UVMF_ALL;
+
+ xen_mc_issue(0);
+}
+
+/*
+ * Perform the hypercall to exchange a region of our pfns to point to
+ * memory with the required contiguous alignment. Takes the pfns as
+ * input, and populates mfns as output.
+ *
+ * Returns a success code indicating whether the hypervisor was able to
+ * satisfy the request or not.
+ */
+int xen_exchange_memory(unsigned long extents_in, unsigned int order_in,
+ unsigned long *pfns_in,
+ unsigned long extents_out, unsigned int order_out,
+ unsigned long *mfns_out,
+ unsigned int address_bits)
+{
+ long rc;
+ int success;
+
+ struct xen_memory_exchange exchange = {
+ .in = {
+ .nr_extents = extents_in,
+ .extent_order = order_in,
+ .extent_start = pfns_in,
+ .domid = DOMID_SELF
+ },
+ .out = {
+ .nr_extents = extents_out,
+ .extent_order = order_out,
+ .extent_start = mfns_out,
+ .address_bits = address_bits,
+ .domid = DOMID_SELF
+ }
+ };
+
+ BUG_ON (extents_in << order_in != extents_out << order_out);
+
+ rc = HYPERVISOR_memory_op(XENMEM_exchange, &exchange);
+ success = (exchange.nr_exchanged == (extents_in << order_in));
+
+ BUG_ON(!success && ((exchange.nr_exchanged != 0) || (rc == 0)));
+ BUG_ON(success && (rc != 0));
+
+ return success;
+}
+
+
+int xen_create_contiguous_region(
+ unsigned long vstart, unsigned int order, unsigned int address_bits)
+{
+ unsigned long *in_frames = discontig_frames, out_frame;
+ unsigned long flags;
+ int success;
+ /*
+ * Currently an auto-translated guest will not perform I/O, nor will
+ * it require PAE page directories below 4GB. Therefore any calls to
+ * this function are redundant and can be ignored.
+ */
+ if (xen_feature(XENFEAT_auto_translated_physmap))
+ return 0;
+
+ if (unlikely(order > MAX_CONTIG_ORDER))
+ return -ENOMEM;
+
+ memset((void *) vstart, 0, PAGE_SIZE << order);
+
+ reservation_lock(flags);
+
+ /* 1. Zap current PTEs, remembering MFNs. */
+ xen_zap_pfn_range(vstart, order, in_frames, NULL);
+
+ /* 2. Get a new contiguous memory extent. */
+ out_frame = virt_to_pfn(vstart);
+ success = xen_exchange_memory(1UL << order, 0, in_frames,
+ 1, order, &out_frame,
+ 0);
+
+ /* 3. Map the new extent in place of old pages. */
+ if (success)
+ xen_remap_exchanged_ptes(vstart, order, NULL, out_frame);
+ else
+ xen_remap_exchanged_ptes(vstart, order, in_frames, 0);
+
+ if (success)
+ contiguous_bitmap_set(virt_to_pfn(vstart), 1UL << order);
+
+ reservation_unlock(flags);
+
+ return success ? 0 : -ENOMEM;
+}
+EXPORT_SYMBOL_GPL(xen_create_contiguous_region);
+
+void xen_destroy_contiguous_region(unsigned long vstart, unsigned int order)
+{
+ unsigned long *out_frames = discontig_frames, in_frame;
+ unsigned long flags;
+ int success;
+
+ if (xen_feature(XENFEAT_auto_translated_physmap) ||
+ !test_bit(virt_to_pfn(vstart), contiguous_bitmap))
+ return;
+
+ if (unlikely(order > MAX_CONTIG_ORDER))
+ return;
+
+ memset((void *) vstart, 0, PAGE_SIZE << order);
+
+ reservation_lock(flags);
+
+ contiguous_bitmap_clear(virt_to_pfn(vstart), 1UL << order);
+
+ /* 1. Find start MFN of contiguous extent. */
+ in_frame = virt_to_mfn(vstart);
+
+ /* 2. Zap current PTEs. */
+ xen_zap_pfn_range(vstart, order, NULL, out_frames);
+
+ /* 3. Do the exchange for non-contiguous MFNs. */
+ success = xen_exchange_memory(1, order, &in_frame,
+ 1UL << order, 0, out_frames,
+ 0);
+
+ /* 4. Map new pages in place of old pages. */
+ if (success)
+ xen_remap_exchanged_ptes(vstart, order, out_frames, 0);
+ else
+ xen_remap_exchanged_ptes(vstart, order, NULL, in_frame);
+
+ reservation_unlock(flags);
+}
+EXPORT_SYMBOL_GPL(xen_destroy_contiguous_region);
diff --git a/include/xen/page.h b/include/xen/page.h
index ce45a6b..b453913 100644
--- a/include/xen/page.h
+++ b/include/xen/page.h
@@ -178,4 +178,21 @@ xmaddr_t arbitrary_virt_to_machine(unsigned long address);
void make_lowmem_page_readonly(void *vaddr);
void make_lowmem_page_readwrite(void *vaddr);
+int xen_create_contiguous_region(unsigned long vstart, unsigned int order,
+ unsigned int address_bits);
+void xen_destroy_contiguous_region(unsigned long vstart, unsigned int order);
+
+/*
+ * Lock the memory reservations of the domain. Can be used to (for
+ * example) prevent a balloon driver from changing the memory
+ * reservation during a driver critical region, but is also used to lock
+ * memory exchanges when changing the page reservations, for example
+ * when creating or destroying contiguous regions.
+ */
+extern spinlock_t reservation_lock;
+#define reservation_lock(__flags) \
+ spin_lock_irqsave(&reservation_lock, (__flags))
+#define reservation_unlock(__flags) \
+ spin_unlock_irqrestore(&reservation_lock, (__flags))
+
#endif /* __XEN_PAGE_H */
--
1.5.4.1
linux-2.6-0035-xen-dom0-Don-t-mask-off-PCD-bits-from-pte-entries.patch:
--- NEW FILE linux-2.6-0035-xen-dom0-Don-t-mask-off-PCD-bits-from-pte-entries.patch ---
>From 7ddc4ba1a0a61549236cba6d84abc8306382822b Mon Sep 17 00:00:00 2001
From: Stephen Tweedie <sct redhat com>
Date: Tue, 29 Jan 2008 16:53:30 +0000
Subject: [PATCH] xen dom0: Don't mask off PCD bits from pte entries.
With pv_ops, Xen is preventing the PAGE_PCD don't-cache pte flag
from being set in any pte. That might be reasonable for domU, but
is certainly not for dom0 --- device drivers genuinely need this
for ioremap_nocache().
If this exposes problems in domU, we'll need to address those
separately.
Suggested by Jeremy Fitzhardinge.
Signed-off-by: Stephen Tweedie <sct redhat com>
---
arch/x86/xen/mmu.c | 4 ----
1 files changed, 0 insertions(+), 4 deletions(-)
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
index 54b6275..bc08a86 100644
--- a/arch/x86/xen/mmu.c
+++ b/arch/x86/xen/mmu.c
@@ -218,8 +218,6 @@ pte_t xen_make_pte(unsigned long long pte)
if (pte & 1)
pte = phys_to_machine(XPADDR(pte)).maddr;
- pte &= ~_PAGE_PCD;
-
return (pte_t){ pte, pte >> 32 };
}
@@ -267,8 +265,6 @@ pte_t xen_make_pte(unsigned long pte)
if (pte & _PAGE_PRESENT)
pte = phys_to_machine(XPADDR(pte)).maddr;
- pte &= ~_PAGE_PCD;
-
return (pte_t){ pte };
}
--
1.5.4.1
linux-2.6-0036-xen-dom0-Remove-duplicate-xen_store_interface-assig.patch:
--- NEW FILE linux-2.6-0036-xen-dom0-Remove-duplicate-xen_store_interface-assig.patch ---
>From 1b8b253b758a9dddf00bf18dbf28e519f83d7a84 Mon Sep 17 00:00:00 2001
From: Mark McLoughlin <markmc redhat com>
Date: Mon, 28 Jan 2008 09:32:31 +0000
Subject: [PATCH] xen dom0: Remove duplicate xen_store_interface assignment
Remove a duplicate line that assigns to xen_store_interface
the same way twice.
Signed-off-by: Mark McLoughlin <markmc redhat com>
---
drivers/xen/xenbus/xenbus_probe.c | 2 --
1 files changed, 0 insertions(+), 2 deletions(-)
diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c
index 298c4c8..17e2657 100644
--- a/drivers/xen/xenbus/xenbus_probe.c
+++ b/drivers/xen/xenbus/xenbus_probe.c
@@ -831,8 +831,6 @@ static int __init xenbus_probe_init(void)
BUG_ON(err);
xen_store_evtchn = xen_start_info->store_evtchn =
alloc_unbound.port;
-
- xen_store_interface = mfn_to_virt(xen_store_mfn);
} else {
xenstored_ready = 1;
xen_store_evtchn = xen_start_info->store_evtchn;
--
1.5.4.1
linux-2.6-0037-xen-dom0-Slightly-re-arrange-xenbus_probe_init-er.patch:
--- NEW FILE linux-2.6-0037-xen-dom0-Slightly-re-arrange-xenbus_probe_init-er.patch ---
>From 6bbb3766d2f1d4ec8f030010ea81e8f390f4c9d6 Mon Sep 17 00:00:00 2001
From: Mark McLoughlin <markmc redhat com>
Date: Mon, 28 Jan 2008 09:44:46 +0000
Subject: [PATCH] xen dom0: Slightly re-arrange xenbus_probe_init() error handling
The dom0 xenstore page should never be allocated at
the out_error label, so only try and free it at
out_unreg_front.
Signed-off-by: Mark McLoughlin <markmc redhat com>
---
drivers/xen/xenbus/xenbus_probe.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c
index 17e2657..1531adf 100644
--- a/drivers/xen/xenbus/xenbus_probe.c
+++ b/drivers/xen/xenbus/xenbus_probe.c
@@ -857,10 +857,10 @@ static int __init xenbus_probe_init(void)
out_unreg_front:
bus_unregister(&xenbus_frontend.bus);
- out_error:
if (page != 0)
free_page(page);
+ out_error:
return err;
}
--
1.5.4.1
linux-2.6-0038-xen-dom0-Use-max_low_pfn-declaration-from-linux-boo.patch:
--- NEW FILE linux-2.6-0038-xen-dom0-Use-max_low_pfn-declaration-from-linux-boo.patch ---
>From 905c016ae31e9898831629dd752bfe5f95161a54 Mon Sep 17 00:00:00 2001
From: Mark McLoughlin <markmc redhat com>
Date: Mon, 28 Jan 2008 16:42:05 +0000
Subject: [PATCH] xen dom0: Use max_low_pfn declaration from linux/bootmem.h
is_local_lowmem() currently declares max_low_pfn itself,
rather than using the declaration in linux/bootmem.h.
Signed-off-by: Mark McLoughlin <markmc redhat com>
---
arch/x86/mm/ioremap_32.c | 2 +-
arch/x86/xen/ioremap.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/x86/mm/ioremap_32.c b/arch/x86/mm/ioremap_32.c
index b4e71f4..3d3810f 100644
--- a/arch/x86/mm/ioremap_32.c
+++ b/arch/x86/mm/ioremap_32.c
@@ -13,6 +13,7 @@
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/io.h>
+#include <linux/bootmem.h>
#include <asm/fixmap.h>
#include <asm/cacheflush.h>
#include <asm/tlbflush.h>
@@ -42,7 +43,6 @@
*/
static inline int is_local_lowmem(unsigned long address)
{
- extern unsigned long max_low_pfn;
if (is_running_on_xen())
return (mfn_to_local_pfn(address >> PAGE_SHIFT) < max_low_pfn);
else
diff --git a/arch/x86/xen/ioremap.c b/arch/x86/xen/ioremap.c
index 4cbbca2..70f77bd 100644
--- a/arch/x86/xen/ioremap.c
+++ b/arch/x86/xen/ioremap.c
@@ -13,6 +13,7 @@
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/io.h>
+#include <linux/bootmem.h>
#include <asm/fixmap.h>
#include <asm/cacheflush.h>
@@ -114,7 +115,6 @@ static int __direct_remap_pfn_range(struct mm_struct *mm,
*/
static inline int is_local_lowmem(unsigned long address)
{
- extern unsigned long max_low_pfn;
return (mfn_to_local_pfn(address >> PAGE_SHIFT) < max_low_pfn);
}
--
1.5.4.1
linux-2.6-0039-xen-dma-Add-dma_mapping_ops-indirection-for-32-bit.patch:
--- NEW FILE linux-2.6-0039-xen-dma-Add-dma_mapping_ops-indirection-for-32-bit.patch ---
>From facec1f45c47be4a882c25d8dd34dffd7b87b8f9 Mon Sep 17 00:00:00 2001
From: Stephen Tweedie <sct redhat com>
Date: Mon, 21 Jan 2008 19:03:54 +0000
Subject: [PATCH] xen dma: Add dma_mapping_ops indirection for 32-bit dma mappings
Uses the same dma_mapping_ops indirections as 64-bit x86, but using
the existing 32-bit implementation underneath. This will provide a
framework into which the Xen swiotlb operations can more cleanly be
hooked at run-time.
Signed-off-by: Stephen Tweedie <sct redhat com>
---
arch/x86/kernel/Makefile_32 | 3 +-
arch/x86/kernel/pci-dma_32.c | 32 +++++++++
arch/x86/kernel/pci-nommu_32.c | 72 ++++++++++++++++++++
arch/x86/mm/init_32.c | 4 +
include/asm-x86/dma-mapping_32.h | 136 ++++++++++++++++++++++----------------
include/asm-x86/pci_32.h | 23 ++++---
6 files changed, 202 insertions(+), 68 deletions(-)
create mode 100644 arch/x86/kernel/pci-nommu_32.c
diff --git a/arch/x86/kernel/Makefile_32 b/arch/x86/kernel/Makefile_32
index 879ed77..e545b89 100644
--- a/arch/x86/kernel/Makefile_32
+++ b/arch/x86/kernel/Makefile_32
@@ -8,7 +8,8 @@ CPPFLAGS_vmlinux.lds += -Ui386
obj-y := process_32.o signal_32.o entry_32.o traps_32.o irq_32.o \
ptrace_32.o time_32.o ioport_32.o ldt_32.o setup_32.o i8259_32.o sys_i386_32.o \
pci-dma_32.o i386_ksyms_32.o i387_32.o bootflag.o e820_32.o\
- quirks.o i8237.o topology.o alternative.o i8253.o tsc_32.o
+ quirks.o i8237.o topology.o alternative.o i8253.o tsc_32.o \
+ pci-nommu_32.o
obj-$(CONFIG_STACKTRACE) += stacktrace.o
obj-y += cpu/
diff --git a/arch/x86/kernel/pci-dma_32.c b/arch/x86/kernel/pci-dma_32.c
index 5133032..04a95c9 100644
--- a/arch/x86/kernel/pci-dma_32.c
+++ b/arch/x86/kernel/pci-dma_32.c
@@ -156,6 +156,38 @@ EXPORT_SYMBOL(dma_mark_declared_memory_occupied);
int forbid_dac;
EXPORT_SYMBOL(forbid_dac);
+int dma_supported(struct device *dev, u64 mask)
+{
+ /*
+ * we fall back to GFP_DMA when the mask isn't all 1s,
+ * so we can't guarantee allocations that must be
+ * within a tighter range than GFP_DMA..
+ */
+ if(mask < 0x00ffffff)
+ return 0;
+
+ /* Work around chipset bugs */
+ if (forbid_dac > 0 && mask > 0xffffffffULL)
+ return 0;
+
+ if (dma_ops->dma_supported)
+ return dma_ops->dma_supported(dev, mask);
+
+ return 1;
+}
+EXPORT_SYMBOL(dma_supported);
+
+int dma_set_mask(struct device *dev, u64 mask)
+{
+ if(!dev->dma_mask || !dma_supported(dev, mask))
+ return -EIO;
+
+ *dev->dma_mask = mask;
+
+ return 0;
+}
+EXPORT_SYMBOL(dma_set_mask);
+
static __devinit void via_no_dac(struct pci_dev *dev)
{
if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI && forbid_dac == 0) {
diff --git a/arch/x86/kernel/pci-nommu_32.c b/arch/x86/kernel/pci-nommu_32.c
new file mode 100644
index 0000000..6a8e3ba
--- /dev/null
+++ b/arch/x86/kernel/pci-nommu_32.c
@@ -0,0 +1,72 @@
+/* Fallback functions when the main IOMMU code is not compiled in. This
+ code is roughly equivalent to i386. */
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/string.h>
+#include <linux/dma-mapping.h>
+#include <linux/scatterlist.h>
+
+#include <asm/processor.h>
+#include <asm/dma.h>
+
+static dma_addr_t
+nommu_map_single(struct device *dev, void *ptr, size_t size,
+ enum dma_data_direction direction)
+{
+ WARN_ON(size == 0);
+ flush_write_buffers();
+ return virt_to_phys(ptr);
+}
+
+static void nommu_unmap_single(struct device *dev, dma_addr_t addr,size_t size,
+ enum dma_data_direction direction)
+{
+}
+
+static int nommu_map_sg(struct device *dev, struct scatterlist *sg,
+ int nents, enum dma_data_direction direction)
+{
+ struct scatterlist *s;
+ int i;
+
+ for_each_sg(sg, s, nents, i) {
+ BUG_ON(!sg_page(s));
+
+ s->dma_address = sg_phys(s);
+ }
+
+ flush_write_buffers();
+ return nents;
+}
+
+/* Unmap a set of streaming mode DMA translations.
+ * Again, cpu read rules concerning calls here are the same as for
+ * pci_unmap_single() above.
+ */
+static void nommu_unmap_sg(struct device *dev, struct scatterlist *sg,
+ int nents, enum dma_data_direction direction)
+{
+}
+
+
+const struct dma_mapping_ops nommu_dma_ops = {
+ .map_single = nommu_map_single,
+ .unmap_single = nommu_unmap_single,
+ .map_sg = nommu_map_sg,
+ .unmap_sg = nommu_unmap_sg,
+ .is_phys = 1,
+};
+
+int __init no_iommu_init(void)
+{
+ if (dma_ops)
+ return 0;
+
+ dma_ops = &nommu_dma_ops;
+ return 0;
+}
+
+
+/* Must execute after PCI subsystem */
+fs_initcall(no_iommu_init);
diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c
index 7287ae4..fcf1be6 100644
--- a/arch/x86/mm/init_32.c
+++ b/arch/x86/mm/init_32.c
@@ -31,6 +31,7 @@
#include <linux/memory_hotplug.h>
#include <linux/initrd.h>
#include <linux/cpumask.h>
+#include <linux/dma-mapping.h>
#include <asm/processor.h>
#include <asm/system.h>
@@ -45,6 +46,9 @@
#include <asm/sections.h>
#include <asm/paravirt.h>
+const struct dma_mapping_ops* dma_ops;
+EXPORT_SYMBOL(dma_ops);
+
unsigned int __VMALLOC_RESERVE = 128 << 20;
DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
diff --git a/include/asm-x86/dma-mapping_32.h b/include/asm-x86/dma-mapping_32.h
index 55f01bd..b14e296 100644
--- a/include/asm-x86/dma-mapping_32.h
+++ b/include/asm-x86/dma-mapping_32.h
@@ -8,6 +8,48 @@
#include <asm/io.h>
#include <asm/bug.h>
+struct dma_mapping_ops {
+ int (*mapping_error)(dma_addr_t dma_addr);
+ void* (*alloc_coherent)(struct device *dev, size_t size,
+ dma_addr_t *dma_handle, gfp_t gfp);
+ void (*free_coherent)(struct device *dev, size_t size,
+ void *vaddr, dma_addr_t dma_handle);
+ dma_addr_t (*map_single)(struct device *hwdev, void *ptr,
+ size_t size, enum dma_data_direction);
+ /* like map_single, but doesn't check the device mask */
+ dma_addr_t (*map_simple)(struct device *hwdev, char *ptr,
+ size_t size, enum dma_data_direction);
+ void (*unmap_single)(struct device *dev, dma_addr_t addr,
+ size_t size, enum dma_data_direction);
+ void (*sync_single_for_cpu)(struct device *hwdev,
+ dma_addr_t dma_handle, size_t size,
+ enum dma_data_direction);
+ void (*sync_single_for_device)(struct device *hwdev,
+ dma_addr_t dma_handle, size_t size,
+ enum dma_data_direction);
+ void (*sync_single_range_for_cpu)(struct device *hwdev,
+ dma_addr_t dma_handle, unsigned long offset,
+ size_t size, enum dma_data_direction);
+ void (*sync_single_range_for_device)(struct device *hwdev,
+ dma_addr_t dma_handle, unsigned long offset,
+ size_t size, enum dma_data_direction);
+ void (*sync_sg_for_cpu)(struct device *hwdev,
+ struct scatterlist *sg, int nelems,
+ enum dma_data_direction);
+ void (*sync_sg_for_device)(struct device *hwdev,
+ struct scatterlist *sg, int nelems,
+ enum dma_data_direction);
+ int (*map_sg)(struct device *hwdev, struct scatterlist *sg,
+ int nents, enum dma_data_direction);
+ void (*unmap_sg)(struct device *hwdev,
+ struct scatterlist *sg, int nents,
+ enum dma_data_direction);
+ int (*dma_supported)(struct device *hwdev, u64 mask);
+ int is_phys;
+};
+
+extern const struct dma_mapping_ops* dma_ops;
+
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
@@ -24,7 +66,7 @@ dma_map_single(struct device *dev, void *ptr, size_t size,
BUG_ON(!valid_dma_direction(direction));
WARN_ON(size == 0);
flush_write_buffers();
- return virt_to_phys(ptr);
+ return dma_ops->map_single(dev, ptr, size, direction);
}
static inline void
@@ -32,61 +74,49 @@ dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
enum dma_data_direction direction)
{
BUG_ON(!valid_dma_direction(direction));
+ dma_ops->unmap_single(dev, dma_addr, size, direction);
}
+#define dma_map_page(dev,page,offset,size,dir) \
+ dma_map_single((dev), page_address(page)+(offset), (size), (dir))
+
+#define dma_unmap_page dma_unmap_single
+
static inline int
dma_map_sg(struct device *dev, struct scatterlist *sglist, int nents,
enum dma_data_direction direction)
{
- struct scatterlist *sg;
- int i;
-
BUG_ON(!valid_dma_direction(direction));
WARN_ON(nents == 0 || sglist[0].length == 0);
-
- for_each_sg(sglist, sg, nents, i) {
- BUG_ON(!sg_page(sg));
-
- sg->dma_address = sg_phys(sg);
- }
-
- flush_write_buffers();
- return nents;
-}
-
-static inline dma_addr_t
-dma_map_page(struct device *dev, struct page *page, unsigned long offset,
- size_t size, enum dma_data_direction direction)
-{
- BUG_ON(!valid_dma_direction(direction));
- return page_to_phys(page) + offset;
+ return dma_ops->map_sg(dev, sglist, nents, direction);
}
static inline void
-dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
- enum dma_data_direction direction)
-{
- BUG_ON(!valid_dma_direction(direction));
-}
-
-
-static inline void
dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
enum dma_data_direction direction)
{
BUG_ON(!valid_dma_direction(direction));
+ dma_ops->unmap_sg(dev, sg, nhwentries, direction);
}
static inline void
dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size,
enum dma_data_direction direction)
{
+ BUG_ON(!valid_dma_direction(direction));
+ if (dma_ops->sync_single_for_cpu)
+ dma_ops->sync_single_for_cpu(dev, dma_handle, size,
+ direction);
}
static inline void
dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, size_t size,
enum dma_data_direction direction)
{
+ BUG_ON(!valid_dma_direction(direction));
+ if (dma_ops->sync_single_for_device)
+ dma_ops->sync_single_for_device(dev, dma_handle, size,
+ direction);
flush_write_buffers();
}
@@ -95,6 +125,10 @@ dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle,
unsigned long offset, size_t size,
enum dma_data_direction direction)
{
+ BUG_ON(!valid_dma_direction(direction));
+ if (dma_ops->sync_single_range_for_cpu)
+ dma_ops->sync_single_range_for_cpu(dev, dma_handle,
+ offset, size, direction);
}
static inline void
@@ -102,6 +136,10 @@ dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle,
unsigned long offset, size_t size,
enum dma_data_direction direction)
{
+ BUG_ON(!valid_dma_direction(direction));
+ if (dma_ops->sync_single_range_for_device)
+ dma_ops->sync_single_range_for_device(dev, dma_handle,
+ offset, size, direction);
flush_write_buffers();
}
@@ -109,51 +147,33 @@ static inline void
dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
enum dma_data_direction direction)
{
+ BUG_ON(!valid_dma_direction(direction));
+ if (dma_ops->sync_sg_for_cpu)
+ dma_ops->sync_sg_for_cpu(dev, sg, nelems, direction);
}
static inline void
dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems,
enum dma_data_direction direction)
{
+ BUG_ON(!valid_dma_direction(direction));
+ if (dma_ops->sync_sg_for_cpu)
+ dma_ops->sync_sg_for_cpu(dev, sg, nelems, direction);
flush_write_buffers();
}
static inline int
dma_mapping_error(dma_addr_t dma_addr)
{
- return 0;
-}
+ if (dma_ops->mapping_error)
+ return dma_ops->mapping_error(dma_addr);
-extern int forbid_dac;
-
-static inline int
-dma_supported(struct device *dev, u64 mask)
-{
- /*
- * we fall back to GFP_DMA when the mask isn't all 1s,
- * so we can't guarantee allocations that must be
- * within a tighter range than GFP_DMA..
- */
- if(mask < 0x00ffffff)
- return 0;
-
- /* Work around chipset bugs */
- if (forbid_dac > 0 && mask > 0xffffffffULL)
- return 0;
-
- return 1;
+ return 0;
}
-static inline int
-dma_set_mask(struct device *dev, u64 mask)
-{
- if(!dev->dma_mask || !dma_supported(dev, mask))
- return -EIO;
-
- *dev->dma_mask = mask;
+extern int dma_supported(struct device *hwdev, u64 mask);
- return 0;
-}
+extern int dma_set_mask(struct device *dev, u64 mask);
static inline int
dma_get_cache_alignment(void)
diff --git a/include/asm-x86/pci_32.h b/include/asm-x86/pci_32.h
index 8c4c3a0..612f63e 100644
--- a/include/asm-x86/pci_32.h
+++ b/include/asm-x86/pci_32.h
@@ -15,15 +15,20 @@ struct pci_dev;
* address space. The networking and block device layers use
* this boolean for bounce buffer decisions.
*/
-#define PCI_DMA_BUS_IS_PHYS (1)
-
-/* pci_unmap_{page,single} is a nop so... */
-#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)
-#define DECLARE_PCI_UNMAP_LEN(LEN_NAME)
-#define pci_unmap_addr(PTR, ADDR_NAME) (0)
-#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) do { } while (0)
-#define pci_unmap_len(PTR, LEN_NAME) (0)
-#define pci_unmap_len_set(PTR, LEN_NAME, VAL) do { } while (0)
+#define PCI_DMA_BUS_IS_PHYS (dma_ops->is_phys)
+
+#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) \
+ dma_addr_t ADDR_NAME;
+#define DECLARE_PCI_UNMAP_LEN(LEN_NAME) \
+ __u32 LEN_NAME;
+#define pci_unmap_addr(PTR, ADDR_NAME) \
+ ((PTR)->ADDR_NAME)
+#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) \
+ (((PTR)->ADDR_NAME) = (VAL))
+#define pci_unmap_len(PTR, LEN_NAME) \
+ ((PTR)->LEN_NAME)
+#define pci_unmap_len_set(PTR, LEN_NAME, VAL) \
+ (((PTR)->LEN_NAME) = (VAL))
#endif /* __KERNEL__ */
--
1.5.4.1
linux-2.6-0040-xen-dma-Remove-unused-32-bit-dma_ops-map_simple-me.patch:
--- NEW FILE linux-2.6-0040-xen-dma-Remove-unused-32-bit-dma_ops-map_simple-me.patch ---
>From 213e0e2c49eeaf47fa466eaf55bdf067d7e4b320 Mon Sep 17 00:00:00 2001
From: Stephen Tweedie <sct redhat com>
Date: Mon, 21 Jan 2008 22:51:56 +0000
Subject: [PATCH] xen dma: Remove unused 32-bit dma_ops->map_simple method
On 64-bit, dma_ops->map_simple is only used in the gart iommu handling.
It's not needed by the 32-bit pci code, so remove it.
Signed-off-by: Stephen Tweedie <sct redhat com>
---
include/asm-x86/dma-mapping_32.h | 3 ---
1 files changed, 0 insertions(+), 3 deletions(-)
diff --git a/include/asm-x86/dma-mapping_32.h b/include/asm-x86/dma-mapping_32.h
index b14e296..db5f2e0 100644
--- a/include/asm-x86/dma-mapping_32.h
+++ b/include/asm-x86/dma-mapping_32.h
@@ -16,9 +16,6 @@ struct dma_mapping_ops {
void *vaddr, dma_addr_t dma_handle);
dma_addr_t (*map_single)(struct device *hwdev, void *ptr,
size_t size, enum dma_data_direction);
- /* like map_single, but doesn't check the device mask */
- dma_addr_t (*map_simple)(struct device *hwdev, char *ptr,
- size_t size, enum dma_data_direction);
void (*unmap_single)(struct device *dev, dma_addr_t addr,
size_t size, enum dma_data_direction);
void (*sync_single_for_cpu)(struct device *hwdev,
--
1.5.4.1
linux-2.6-0041-xen-dma-Initial-commit-of-pci-xen.c-dma-mapping-fun.patch:
--- NEW FILE linux-2.6-0041-xen-dma-Initial-commit-of-pci-xen.c-dma-mapping-fun.patch ---
>From 15257ab609ca909111c424377a331d95e8739c65 Mon Sep 17 00:00:00 2001
From: Stephen Tweedie <sct redhat com>
Date: Tue, 22 Jan 2008 17:01:48 +0000
Subject: [PATCH] xen dma: Initial commit of pci-xen.c dma mapping functions.
Adds pci-xen.c, detectable at runtime, for the Xen DMA mapping
functions.
Signed-off-by: Stephen Tweedie <sct redhat com>
---
arch/x86/kernel/Makefile_32 | 2 +
arch/x86/kernel/pci-dma_32.c | 13 +++
arch/x86/kernel/pci-nommu_32.c | 4 -
arch/x86/kernel/pci-xen.c | 162 ++++++++++++++++++++++++++++++++++++++++
include/asm-x86/iommu.h | 30 +-------
include/asm-x86/iommu_32.h | 9 ++
include/asm-x86/iommu_64.h | 29 +++++++
7 files changed, 218 insertions(+), 31 deletions(-)
create mode 100644 arch/x86/kernel/pci-xen.c
create mode 100644 include/asm-x86/iommu_32.h
create mode 100644 include/asm-x86/iommu_64.h
diff --git a/arch/x86/kernel/Makefile_32 b/arch/x86/kernel/Makefile_32
index e545b89..ab491bb 100644
--- a/arch/x86/kernel/Makefile_32
+++ b/arch/x86/kernel/Makefile_32
@@ -50,6 +50,8 @@ obj-y += pcspeaker.o
obj-$(CONFIG_SCx200) += scx200_32.o
+obj-$(CONFIG_XEN) += pci-xen.o
+
# vsyscall_32.o contains the vsyscall DSO images as __initdata.
# We must build both images before we can assemble it.
# Note: kbuild does not track this dependency due to usage of .incbin
diff --git a/arch/x86/kernel/pci-dma_32.c b/arch/x86/kernel/pci-dma_32.c
index 04a95c9..6df2e1a 100644
--- a/arch/x86/kernel/pci-dma_32.c
+++ b/arch/x86/kernel/pci-dma_32.c
@@ -13,6 +13,7 @@
#include <linux/pci.h>
#include <linux/module.h>
#include <asm/io.h>
+#include <asm/iommu.h>
struct dma_coherent_mem {
void *virt_base;
@@ -150,6 +151,16 @@ void *dma_mark_declared_memory_occupied(struct device *dev,
}
EXPORT_SYMBOL(dma_mark_declared_memory_occupied);
+static int __init pci_iommu_init(void)
+{
+#ifdef CONFIG_XEN
+ xen_iommu_init();
+#endif
+
+ no_iommu_init();
+ return 0;
+}
+
#ifdef CONFIG_PCI
/* Many VIA bridges seem to corrupt data for DAC. Disable it here */
@@ -207,3 +218,5 @@ static int check_iommu(char *s)
}
__setup("iommu=", check_iommu);
#endif
+/* Must execute after PCI subsystem */
+fs_initcall(pci_iommu_init);
diff --git a/arch/x86/kernel/pci-nommu_32.c b/arch/x86/kernel/pci-nommu_32.c
index 6a8e3ba..ed7f5af 100644
--- a/arch/x86/kernel/pci-nommu_32.c
+++ b/arch/x86/kernel/pci-nommu_32.c
@@ -66,7 +66,3 @@ int __init no_iommu_init(void)
dma_ops = &nommu_dma_ops;
return 0;
}
-
-
-/* Must execute after PCI subsystem */
-fs_initcall(no_iommu_init);
diff --git a/arch/x86/kernel/pci-xen.c b/arch/x86/kernel/pci-xen.c
new file mode 100644
index 0000000..6967a33
--- /dev/null
+++ b/arch/x86/kernel/pci-xen.c
@@ -0,0 +1,162 @@
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/string.h>
+#include <linux/dma-mapping.h>
+#include <linux/scatterlist.h>
+
+#include <asm/processor.h>
+#include <asm/dma.h>
+#include <asm/xen/hypervisor.h>
+
+#include <xen/page.h>
+
+#define IOMMU_BUG_ON(test) \
+do { \
+ if (unlikely(test)) { \
+ printk(KERN_ALERT "Fatal DMA error! " \
+ "Please use 'swiotlb=force' " \
+ "once we implement it.\n"); \
+ BUG(); \
+ } \
+} while (0)
+
+static inline int
+address_needs_mapping(struct device *hwdev, dma_addr_t addr)
+{
+ dma_addr_t mask = 0xffffffff;
+ /* If the device has a mask, use it, otherwise default to 32 bits */
+ if (hwdev && hwdev->dma_mask)
+ mask = *hwdev->dma_mask;
+ return (addr & ~mask) != 0;
+}
+
+static int
+range_straddles_page_boundary(struct page *page, unsigned int offset,
+ size_t size)
+{
+ unsigned long pfn;
+ xpaddr_t phys;
+ extern unsigned long *contiguous_bitmap;
+ extern unsigned long max_low_pfn;
+
+ phys = XPADDR(page_to_phys(page));
+ if (((phys.paddr & ~PAGE_MASK) + size) <= PAGE_SIZE)
+ return 0;
+
+ pfn = page_to_pfn(page);
+ if (pfn < max_low_pfn && test_bit(pfn, contiguous_bitmap))
+ return 0;
+
+ printk(KERN_WARNING "DMA range crosses page boundary: "
+ "0x%016Lx+0x%04x\n", phys.paddr, size);
+ return 1;
+}
+
+static inline dma_addr_t xen_dma_map_page(struct page *page)
+{
+ /* Xen TODO: 2.6.18 xen calls __gnttab_dma_map_page here to deal
+ * with foreign pages. We'll need similar logic here at some
+ * point. */
+ return ((dma_addr_t)pfn_to_mfn(page_to_pfn(page))) << PAGE_SHIFT;
+}
+
+static inline void xen_dma_unmap_page(dma_addr_t p)
+{
+ /* Xen TODO: 2.6.18 xen calls __gnttab_dma_unmap_page_page here
+ * to deal with foreign pages. We'll need similar logic here at
+ * some point. */
+}
+
+static dma_addr_t
+xen_map_single(struct device *dev, void *ptr, size_t size,
+ enum dma_data_direction direction)
+{
+ dma_addr_t dma;
+ struct page *page = virt_to_page(ptr);
+ xpaddr_t phys = XPADDR(virt_to_phys(ptr));
+
+ BUG_ON(ptr == NULL);
+ WARN_ON(size == 0);
+
+ flush_write_buffers();
+
+ dma = xen_dma_map_page(page) + offset_in_page(ptr);
+ IOMMU_BUG_ON(range_straddles_page_boundary(
+ page, phys.paddr & ~PAGE_MASK, size));
+ IOMMU_BUG_ON(address_needs_mapping(dev, dma));
+
+ return dma;
+}
+
+static void xen_unmap_single(struct device *dev, dma_addr_t addr,size_t size,
+ enum dma_data_direction direction)
+{
+ xen_dma_unmap_page(addr);
+}
+
+static int xen_map_sg(struct device *dev, struct scatterlist *sg,
+ int nents, enum dma_data_direction direction)
+{
+ struct scatterlist *s;
+ int i;
+
+ if (direction == DMA_NONE)
+ BUG();
+
+ for_each_sg(sg, s, nents, i) {
+ struct page *page = sg_page(s);
+
+ BUG_ON(!page);
+
+ /* Xen TODO: Why does 2.6.18 xen also set s->dma_length
+ * here? And do we still need to? */
+
+ s->dma_address = xen_dma_map_page(page) + s->offset;
+
+ IOMMU_BUG_ON(address_needs_mapping(
+ dev, s->dma_address));
+ IOMMU_BUG_ON(range_straddles_page_boundary(
+ page, s->offset, s->length));
+ }
+
+ flush_write_buffers();
+ return nents;
+}
+
+static void xen_unmap_sg(struct device *dev, struct scatterlist *sg,
+ int nents, enum dma_data_direction direction)
+{
+ struct scatterlist *s;
+ int i;
+
+ if (direction == DMA_NONE)
+ BUG();
+
+ for_each_sg(sg, s, nents, i)
+ xen_dma_unmap_page(s->dma_address);
+}
+
+
+const struct dma_mapping_ops xen_dma_ops = {
+ .map_single = xen_map_single,
+ .unmap_single = xen_unmap_single,
+ .map_sg = xen_map_sg,
+ .unmap_sg = xen_unmap_sg,
+ /* Xen TODO: Is this right even if we have no swiotlb
+ * installed? */
+ .is_phys = 0,
+};
+
+int __init xen_iommu_init(void)
+{
+ if (!is_running_on_xen())
+ return 0;
+ if (!is_initial_xendomain())
+ return 0;
+
+ BUG_ON(dma_ops);
+ dma_ops = &xen_dma_ops;
+ printk(KERN_INFO "Installed Xen dma mapping ops (no swiotlb)\n");
+ return 0;
+}
diff --git a/include/asm-x86/iommu.h b/include/asm-x86/iommu.h
index 07862fd..9f8a9ef 100644
--- a/include/asm-x86/iommu.h
+++ b/include/asm-x86/iommu.h
@@ -1,29 +1,5 @@
-#ifndef _ASM_X8664_GART_H
-#define _ASM_X8664_GART_H 1
-
-extern void pci_iommu_shutdown(void);
-extern void no_iommu_init(void);
-extern int force_iommu, no_iommu;
-extern int iommu_detected;
-#ifdef CONFIG_IOMMU
-extern void gart_iommu_init(void);
-extern void gart_iommu_shutdown(void);
-extern void __init gart_parse_options(char *);
-extern void iommu_hole_init(void);
-extern int fallback_aper_order;
-extern int fallback_aper_force;
-extern int iommu_aperture;
-extern int iommu_aperture_allowed;
-extern int iommu_aperture_disabled;
-extern int fix_aperture;
+#ifdef CONFIG_X86_32
+# include "iommu_32.h"
#else
-#define iommu_aperture 0
-#define iommu_aperture_allowed 0
-
-static inline void gart_iommu_shutdown(void)
-{
-}
-
-#endif
-
+# include "iommu_64.h"
#endif
diff --git a/include/asm-x86/iommu_32.h b/include/asm-x86/iommu_32.h
new file mode 100644
index 0000000..4bc3e8a
--- /dev/null
+++ b/include/asm-x86/iommu_32.h
@@ -0,0 +1,9 @@
+#ifndef _ASM_X86_IOMMU_H
+#define _ASM_X86_IOMMU_H 1
+
+extern void no_iommu_init(void);
+#ifdef CONFIG_XEN
+extern void xen_iommu_init(void);
+#endif
+
+#endif
diff --git a/include/asm-x86/iommu_64.h b/include/asm-x86/iommu_64.h
new file mode 100644
index 0000000..07862fd
--- /dev/null
+++ b/include/asm-x86/iommu_64.h
@@ -0,0 +1,29 @@
+#ifndef _ASM_X8664_GART_H
+#define _ASM_X8664_GART_H 1
+
+extern void pci_iommu_shutdown(void);
+extern void no_iommu_init(void);
+extern int force_iommu, no_iommu;
+extern int iommu_detected;
+#ifdef CONFIG_IOMMU
+extern void gart_iommu_init(void);
+extern void gart_iommu_shutdown(void);
+extern void __init gart_parse_options(char *);
+extern void iommu_hole_init(void);
+extern int fallback_aper_order;
+extern int fallback_aper_force;
+extern int iommu_aperture;
+extern int iommu_aperture_allowed;
+extern int iommu_aperture_disabled;
+extern int fix_aperture;
+#else
+#define iommu_aperture 0
+#define iommu_aperture_allowed 0
+
+static inline void gart_iommu_shutdown(void)
+{
+}
+
+#endif
+
+#endif
--
1.5.4.1
linux-2.6-0042-xen-dma-Add-calls-to-dma_ops-alloc-free_coherent-ho.patch:
--- NEW FILE linux-2.6-0042-xen-dma-Add-calls-to-dma_ops-alloc-free_coherent-ho.patch ---
>From 0f4965d087c23fa5d3c351724003aecb5881e037 Mon Sep 17 00:00:00 2001
From: Stephen Tweedie <sct redhat com>
Date: Wed, 30 Jan 2008 21:53:48 +0000
Subject: [PATCH] xen dma: Add calls to dma_ops alloc/free_coherent hooks.
Signed-off-by: Stephen Tweedie <sct redhat com>
---
arch/x86/kernel/pci-dma_32.c | 11 +++++++++--
1 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/arch/x86/kernel/pci-dma_32.c b/arch/x86/kernel/pci-dma_32.c
index 6df2e1a..b983dc0 100644
--- a/arch/x86/kernel/pci-dma_32.c
+++ b/arch/x86/kernel/pci-dma_32.c
@@ -48,6 +48,9 @@ void *dma_alloc_coherent(struct device *dev, size_t size,
if (dev == NULL || (dev->coherent_dma_mask < 0xffffffff))
gfp |= GFP_DMA;
+ if (dma_ops->alloc_coherent)
+ return dma_ops->alloc_coherent(dev, size, dma_handle, gfp);
+
ret = (void *)__get_free_pages(gfp, order);
if (ret != NULL) {
@@ -69,8 +72,12 @@ void dma_free_coherent(struct device *dev, size_t size,
int page = (vaddr - mem->virt_base) >> PAGE_SHIFT;
bitmap_release_region(mem->bitmap, page, order);
- } else
- free_pages((unsigned long)vaddr, order);
+ } else {
+ if (dma_ops->free_coherent)
+ dma_ops->free_coherent(dev, size, vaddr, dma_handle);
+ else
+ free_pages((unsigned long)vaddr, order);
+ }
}
EXPORT_SYMBOL(dma_free_coherent);
--
1.5.4.1
linux-2.6-0043-xen-dma-Add-xen_alloc-free_coherent.patch:
--- NEW FILE linux-2.6-0043-xen-dma-Add-xen_alloc-free_coherent.patch ---
>From f33c0f237ea698a756b4c04926c09c407a731705 Mon Sep 17 00:00:00 2001
From: Stephen Tweedie <sct redhat com>
Date: Thu, 31 Jan 2008 11:49:04 +0000
Subject: [PATCH] xen dma: Add xen_alloc/free_coherent
Add dma_ops-based xen-specific dma_alloc/free_coherent functions,
using the xen contiguous region calls to obtain DMA-capable
memory.
Signed-off-by: Stephen Tweedie <sct redhat com>
---
arch/x86/kernel/pci-xen.c | 42 ++++++++++++++++++++++++++++++++++++++++++
1 files changed, 42 insertions(+), 0 deletions(-)
diff --git a/arch/x86/kernel/pci-xen.c b/arch/x86/kernel/pci-xen.c
index 6967a33..2f92422 100644
--- a/arch/x86/kernel/pci-xen.c
+++ b/arch/x86/kernel/pci-xen.c
@@ -137,8 +137,50 @@ static void xen_unmap_sg(struct device *dev, struct scatterlist *sg,
xen_dma_unmap_page(s->dma_address);
}
+static void *xen_alloc_coherent(struct device *dev, size_t size,
+ dma_addr_t *dma_handle, gfp_t gfp)
+{
+ unsigned int order = get_order(size);
+ unsigned long vstart;
+ dma_addr_t mask;
+ void *ret;
+
+ vstart = __get_free_pages(gfp, order);
+ ret = (void *)vstart;
+
+ if (ret == NULL)
+ return NULL;
+
+ if (dev != NULL && dev->coherent_dma_mask)
+ mask = dev->coherent_dma_mask;
+ else
+ mask = 0xffffffff;
+
+ if (xen_create_contiguous_region(vstart, order,
+ fls64(mask)) != 0) {
+ free_pages(vstart, order);
+ return NULL;
+ }
+
+ memset(ret, 0, size);
+ *dma_handle = virt_to_machine(ret).maddr;
+
+ return ret;
+}
+
+static void xen_free_coherent(struct device *dev, size_t size,
+ void *vaddr, dma_addr_t dma_handle)
+{
+ int order = get_order(size);
+
+ xen_destroy_contiguous_region((unsigned long)vaddr, order);
+ free_pages((unsigned long)vaddr, order);
+}
+
const struct dma_mapping_ops xen_dma_ops = {
+ .alloc_coherent = xen_alloc_coherent,
+ .free_coherent = xen_free_coherent,
.map_single = xen_map_single,
.unmap_single = xen_unmap_single,
.map_sg = xen_map_sg,
--
1.5.4.1
linux-2.6-0044-xen-dma-Don-t-merge-bios-on-xen-pvops.patch:
--- NEW FILE linux-2.6-0044-xen-dma-Don-t-merge-bios-on-xen-pvops.patch ---
>From ac9db3990366b613147e45bd0e7ceb4cc4501854 Mon Sep 17 00:00:00 2001
From: Stephen Tweedie <sct redhat com>
Date: Fri, 1 Feb 2008 18:04:53 +0000
Subject: [PATCH] xen dma: Don't merge bios on xen pvops.
On Xen, pages which are pseudophysically contiguous may not be
machine-contiguous. So the normal bio rules for merging adjacent
bios do not apply. And if Xen is running with no swiotlb, then
it has no mechanism for unpicking such merged bio segments.
Add a switch to turn of such merging, so that pvops xen can prevent
it.
We add the switch in the form of a simple extern variable, in
order to prevent the whole paravirt-ops infrastructure from being
pulled into io.h.
We might consider changing this to have an arch-supplied bio merge
function, so that xen can determine whether any two bios are in
fact machine-contiguous.
Signed-off-by: Stephen Tweedie <sct redhat com>
---
arch/x86/kernel/pci-dma_32.c | 9 +++++++++
arch/x86/kernel/pci-xen.c | 1 +
include/asm-x86/io_32.h | 12 ++++++++++++
3 files changed, 22 insertions(+), 0 deletions(-)
diff --git a/arch/x86/kernel/pci-dma_32.c b/arch/x86/kernel/pci-dma_32.c
index b983dc0..ce05946 100644
--- a/arch/x86/kernel/pci-dma_32.c
+++ b/arch/x86/kernel/pci-dma_32.c
@@ -15,6 +15,15 @@
#include <asm/io.h>
#include <asm/iommu.h>
+/*
+ * Determine whether the bio layer is permitted to merge sg entries
+ * across physically-contiguous pages.
+ *
+ * True unless a specific dma driver tells us otherwise.
+ */
+int __biovec_phys_mergeable = 1;
+EXPORT_SYMBOL(__biovec_phys_mergeable);
+
struct dma_coherent_mem {
void *virt_base;
u32 device_base;
diff --git a/arch/x86/kernel/pci-xen.c b/arch/x86/kernel/pci-xen.c
index 2f92422..73f27d4 100644
--- a/arch/x86/kernel/pci-xen.c
+++ b/arch/x86/kernel/pci-xen.c
@@ -199,6 +199,7 @@ int __init xen_iommu_init(void)
BUG_ON(dma_ops);
dma_ops = &xen_dma_ops;
+ __biovec_phys_mergeable = 0;
printk(KERN_INFO "Installed Xen dma mapping ops (no swiotlb)\n");
return 0;
}
diff --git a/include/asm-x86/io_32.h b/include/asm-x86/io_32.h
index e2b916e..6344856 100644
--- a/include/asm-x86/io_32.h
+++ b/include/asm-x86/io_32.h
@@ -95,6 +95,18 @@ static inline void * phys_to_virt(unsigned long address)
return __va(address);
}
+struct bio_vec;
+
+/*
+ * Allow for paravirt drivers to determine physical bio mergeability for
+ * themselves, as virtualised environments may not necessary allow for
+ * dma across contiguous pfns.
+ */
+extern int __biovec_phys_mergeable;
+#define BIOVEC_PHYS_MERGEABLE(vec1, vec2) \
+ (((bvec_to_phys((vec1)) + (vec1)->bv_len) == bvec_to_phys((vec2))) && \
+ (__biovec_phys_mergeable != 0))
+
/*
* Change "struct page" to physical address.
*/
--
1.5.4.1
linux-2.6-0045-xen-dom0-Minor-coding-style-issue-in-ISA-mapping-co.patch:
--- NEW FILE linux-2.6-0045-xen-dom0-Minor-coding-style-issue-in-ISA-mapping-co.patch ---
>From f834f38a5c22552015cc00dbc64139cada2c2610 Mon Sep 17 00:00:00 2001
From: Mark McLoughlin <markmc redhat com>
Date: Fri, 1 Feb 2008 10:15:18 +0000
Subject: [PATCH] xen dom0: Minor coding style issue in ISA mapping code
Signed-off-by: Mark McLoughlin <markmc redhat com>
---
arch/x86/xen/enlighten.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index a11607a..5719b8f 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -873,7 +873,7 @@ static __init void xen_pagetable_setup_done(pgd_t *base)
* If we're dom0, then 1:1 map the ISA machine addresses
* into the kernel's address space.
*/
- for(i = ISA_START_ADDRESS; i < ISA_END_ADDRESS; i += PAGE_SIZE)
+ for (i = ISA_START_ADDRESS; i < ISA_END_ADDRESS; i += PAGE_SIZE)
set_pte_mfn(PAGE_OFFSET + i, PFN_DOWN(i), PAGE_KERNEL);
reserve_bootmem(ISA_START_ADDRESS, ISA_END_ADDRESS - ISA_START_ADDRESS);
--
1.5.4.1
linux-2.6-0046-xen-dom0-Use-i-PAGE_SHIFT-instead-of-PAGE_DOWN-i.patch:
--- NEW FILE linux-2.6-0046-xen-dom0-Use-i-PAGE_SHIFT-instead-of-PAGE_DOWN-i.patch ---
>From 93ffa1eae323db8e86c4277bb627f993ea7c84bd Mon Sep 17 00:00:00 2001
From: Mark McLoughlin <markmc redhat com>
Date: Fri, 1 Feb 2008 10:17:05 +0000
Subject: [PATCH] xen dom0: Use i >> PAGE_SHIFT instead of PAGE_DOWN(i)
It's the same thing, but when dealing with page aligned
addresses, it looks like it's more usual to not use
the macro. Also, it's a tiny bit more obvious what's
going on.
Signed-off-by: Mark McLoughlin <markmc redhat com>
---
arch/x86/xen/enlighten.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index 5719b8f..363a4f5 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -874,7 +874,7 @@ static __init void xen_pagetable_setup_done(pgd_t *base)
* into the kernel's address space.
*/
for (i = ISA_START_ADDRESS; i < ISA_END_ADDRESS; i += PAGE_SIZE)
- set_pte_mfn(PAGE_OFFSET + i, PFN_DOWN(i), PAGE_KERNEL);
+ set_pte_mfn(PAGE_OFFSET + i, i >> PAGE_SHIFT, PAGE_KERNEL);
reserve_bootmem(ISA_START_ADDRESS, ISA_END_ADDRESS - ISA_START_ADDRESS);
printk(KERN_INFO "Xen: setup ISA identity maps\n");
--
1.5.4.1
linux-2.6-0047-xen-dom0-Match-up-set_pte_mfn-prototype-with-the.patch:
--- NEW FILE linux-2.6-0047-xen-dom0-Match-up-set_pte_mfn-prototype-with-the.patch ---
>From 2db238704dd7015ef03bc6d070da5b73b4c64cec Mon Sep 17 00:00:00 2001
From: Mark McLoughlin <markmc redhat com>
Date: Fri, 1 Feb 2008 10:19:02 +0000
Subject: [PATCH] xen dom0: Match up set_pte_mfn() prototype with the impl
Signed-off-by: Mark McLoughlin <markmc redhat com>
---
arch/x86/xen/mmu.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/arch/x86/xen/mmu.h b/arch/x86/xen/mmu.h
index 8594c92..34b1757 100644
--- a/arch/x86/xen/mmu.h
+++ b/arch/x86/xen/mmu.h
@@ -16,7 +16,7 @@
#define xen_cr3_to_pfn(cr3) (((unsigned)(cr3) >> 12) | ((unsigned)(cr3) << 20))
-void set_pte_mfn(unsigned long vaddr, unsigned long pfn, pgprot_t flags);
+void set_pte_mfn(unsigned long vaddr, unsigned long mfn, pgprot_t flags);
void xen_set_pte(pte_t *ptep, pte_t pteval);
void xen_set_pte_at(struct mm_struct *mm, unsigned long addr,
--
1.5.4.1
linux-2.6-0048-xen-dom0-Reserve-ISA-address-space-earlier.patch:
--- NEW FILE linux-2.6-0048-xen-dom0-Reserve-ISA-address-space-earlier.patch ---
>From 34721eeb0f38e7fe8567a47bc9aa0f3328b55d52 Mon Sep 17 00:00:00 2001
From: Mark McLoughlin <markmc redhat com>
Date: Fri, 1 Feb 2008 15:08:26 +0000
Subject: [PATCH] xen dom0: Reserve ISA address space earlier
Reserve the ISA address space earlier so as to prevent
pmd/pte pages from being allocated there. Otherwise
we run the risk of some page tables being blown away
later when we remap that region.
Signed-off-by: Mark McLoughlin <markmc redhat com>
---
arch/x86/xen/enlighten.c | 8 +++++++-
1 files changed, 7 insertions(+), 1 deletions(-)
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index 363a4f5..0866c20 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -794,6 +794,13 @@ static __init void xen_pagetable_setup_start(pgd_t *base)
*/
memcpy(base, xen_pgd, PTRS_PER_PGD * sizeof(pgd_t));
+ /*
+ * If we're dom0, then reserve the ISA address space
+ * so that pmd/pte pages don't get allocated there.
+ */
+ if (is_initial_xendomain())
+ reserve_bootmem(ISA_START_ADDRESS, ISA_END_ADDRESS - ISA_START_ADDRESS);
+
if (PTRS_PER_PMD > 1) {
int i;
/*
@@ -876,7 +883,6 @@ static __init void xen_pagetable_setup_done(pgd_t *base)
for (i = ISA_START_ADDRESS; i < ISA_END_ADDRESS; i += PAGE_SIZE)
set_pte_mfn(PAGE_OFFSET + i, i >> PAGE_SHIFT, PAGE_KERNEL);
- reserve_bootmem(ISA_START_ADDRESS, ISA_END_ADDRESS - ISA_START_ADDRESS);
printk(KERN_INFO "Xen: setup ISA identity maps\n");
/*
--
1.5.4.1
linux-2.6-0049-xen-Add-empty-xenctrl-module.patch:
--- NEW FILE linux-2.6-0049-xen-Add-empty-xenctrl-module.patch ---
>From 8a2b660e6a45e4f441cbf163df2501b0bd8ecb63 Mon Sep 17 00:00:00 2001
From: Mark McLoughlin <markmc redhat com>
Date: Mon, 4 Feb 2008 08:30:37 +0000
Subject: [PATCH] xen: Add empty xenctrl module
Add the basic infrastructure for a xenctrl module
which will contain the various kernel interfaces
used by (mainly Dom0) Xen userspace.
Signed-off-by: Mark McLoughlin <markmc redhat com>
---
arch/x86/xen/Kconfig | 11 +++++++
drivers/xen/Makefile | 2 +
drivers/xen/xenctrl/Makefile | 4 +++
drivers/xen/xenctrl/main.c | 62 ++++++++++++++++++++++++++++++++++++++++++
4 files changed, 79 insertions(+), 0 deletions(-)
create mode 100644 drivers/xen/xenctrl/Makefile
create mode 100644 drivers/xen/xenctrl/main.c
diff --git a/arch/x86/xen/Kconfig b/arch/x86/xen/Kconfig
index fbfa55c..7f01d14 100644
--- a/arch/x86/xen/Kconfig
+++ b/arch/x86/xen/Kconfig
@@ -10,3 +10,14 @@ config XEN
This is the Linux Xen port. Enabling this will allow the
kernel to boot in a paravirtualized environment under the
Xen hypervisor.
+
+config XENCTRL
+ tristate "Xen's user space control interfaces"
+ depends on XEN && PROC_FS
+ default m if XEN
+ help
+ This is the /proc/xen and /dev/evtchn interfaces used by
+ Xen's libxc and xenstored.
+
+ Enable this if you wish to use this kernel to boot a
+ privileged (i.e. Dom0) Xen guest.
diff --git a/drivers/xen/Makefile b/drivers/xen/Makefile
index 56592f0..6737463 100644
--- a/drivers/xen/Makefile
+++ b/drivers/xen/Makefile
@@ -1,2 +1,4 @@
obj-y += grant-table.o
obj-y += xenbus/
+
+obj-$(CONFIG_XENCTRL) += xenctrl/
diff --git a/drivers/xen/xenctrl/Makefile b/drivers/xen/xenctrl/Makefile
new file mode 100644
index 0000000..1f43a43
--- /dev/null
+++ b/drivers/xen/xenctrl/Makefile
@@ -0,0 +1,4 @@
+obj-$(CONFIG_XENCTRL) += xenctrl.o
+
+xenctrl-objs =
+xenctrl-objs += main.o
diff --git a/drivers/xen/xenctrl/main.c b/drivers/xen/xenctrl/main.c
new file mode 100644
index 0000000..2965ceb
--- /dev/null
+++ b/drivers/xen/xenctrl/main.c
@@ -0,0 +1,62 @@
+/******************************************************************************
+ *
+ * main.c
+ *
+ * Xen userspace control interfaces
+ *
+ * Copyright (c) 2002-2004, K A Fraser, B Dragovic
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation; or, when distributed
+ * separately from the Linux kernel or incorporated into other
+ * software packages, subject to the following license:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this source file (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <linux/proc_fs.h>
+#include <linux/module.h>
+#include <asm/xen/hypervisor.h>
+
+static int __init xenctrl_init(void)
+{
+ struct proc_dir_entry *dir;
+
+ if (!is_running_on_xen())
+ return -ENODEV;
+
+ dir = proc_mkdir("xen", NULL);
+ if (!dir)
+ return -ENOMEM;
+
+ dir->owner = THIS_MODULE;
+
+ return 0;
+}
+
+static void __exit xenctrl_exit(void)
+{
+ remove_proc_entry("xen", NULL);
+}
+
+module_init(xenctrl_init);
+module_exit(xenctrl_exit);
+
+MODULE_LICENSE("Dual BSD/GPL");
--
1.5.4.1
linux-2.6-0050-xen-dom0-Add-proc-xen-capabilities.patch:
--- NEW FILE linux-2.6-0050-xen-dom0-Add-proc-xen-capabilities.patch ---
>From ff8d1ce07961633c01846fc746c863bca53550df Mon Sep 17 00:00:00 2001
From: Mark McLoughlin <markmc redhat com>
Date: Mon, 4 Feb 2008 09:16:51 +0000
Subject: [PATCH] xen dom0: Add /proc/xen/capabilities
/proc/xen/capabilities is used by the xend init script
to check whether it is running on Dom0.
Signed-off-by: Mark McLoughlin <markmc redhat com>
---
drivers/xen/xenctrl/Makefile | 1 +
drivers/xen/xenctrl/capabilities.c | 68 ++++++++++++++++++++++++++++++++++++
drivers/xen/xenctrl/main.c | 11 ++++++
drivers/xen/xenctrl/xenctrl.h | 37 +++++++++++++++++++
4 files changed, 117 insertions(+), 0 deletions(-)
create mode 100644 drivers/xen/xenctrl/capabilities.c
create mode 100644 drivers/xen/xenctrl/xenctrl.h
diff --git a/drivers/xen/xenctrl/Makefile b/drivers/xen/xenctrl/Makefile
index 1f43a43..631f535 100644
--- a/drivers/xen/xenctrl/Makefile
+++ b/drivers/xen/xenctrl/Makefile
@@ -2,3 +2,4 @@ obj-$(CONFIG_XENCTRL) += xenctrl.o
xenctrl-objs =
xenctrl-objs += main.o
+xenctrl-objs += capabilities.o
diff --git a/drivers/xen/xenctrl/capabilities.c b/drivers/xen/xenctrl/capabilities.c
new file mode 100644
index 0000000..66443fb
--- /dev/null
+++ b/drivers/xen/xenctrl/capabilities.c
@@ -0,0 +1,68 @@
+/******************************************************************************
+ *
+ * capabilities.c
+ *
+ * /proc/xen/capabilities
+ *
+ * Copyright (c) 2002-2004, K A Fraser, B Dragovic
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation; or, when distributed
+ * separately from the Linux kernel or incorporated into other
+ * software packages, subject to the following license:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this source file (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <linux/proc_fs.h>
+#include <linux/module.h>
+#include <asm/xen/hypervisor.h>
+
+static int capabilities_read(char *page, char **start, off_t off,
+ int count, int *eof, void *data)
+{
+ int len = 0;
+ *page = 0;
+
+ if (is_initial_xendomain())
+ len = sprintf(page, "control_d\n");
+
+ *eof = 1;
+ return len;
+}
+
+int capabilities_create_proc_entry(void)
+{
+ struct proc_dir_entry *entry;
+
+ entry = create_proc_entry("xen/capabilities", 0400, NULL);
+ if (!entry)
+ return -ENOMEM;
+
+ entry->owner = THIS_MODULE;
+ entry->read_proc = capabilities_read;
+
+ return 0;
+}
+
+void capabilities_remove_proc_entry(void)
+{
+ remove_proc_entry("xen/capabilities", NULL);
+}
diff --git a/drivers/xen/xenctrl/main.c b/drivers/xen/xenctrl/main.c
index 2965ceb..0e42f7e 100644
--- a/drivers/xen/xenctrl/main.c
+++ b/drivers/xen/xenctrl/main.c
@@ -31,6 +31,8 @@
* IN THE SOFTWARE.
*/
+#include "xenctrl.h"
+
#include <linux/proc_fs.h>
#include <linux/module.h>
#include <asm/xen/hypervisor.h>
@@ -38,6 +40,7 @@
static int __init xenctrl_init(void)
{
struct proc_dir_entry *dir;
+ int ret;
if (!is_running_on_xen())
return -ENODEV;
@@ -48,11 +51,19 @@ static int __init xenctrl_init(void)
dir->owner = THIS_MODULE;
+ ret = capabilities_create_proc_entry();
+ if (ret)
+ goto fail1;
+
return 0;
+
+ fail1: remove_proc_entry("xen", NULL);
+ return ret;
}
static void __exit xenctrl_exit(void)
{
+ capabilities_remove_proc_entry();
remove_proc_entry("xen", NULL);
}
diff --git a/drivers/xen/xenctrl/xenctrl.h b/drivers/xen/xenctrl/xenctrl.h
new file mode 100644
index 0000000..e90e588
--- /dev/null
+++ b/drivers/xen/xenctrl/xenctrl.h
@@ -0,0 +1,37 @@
+/******************************************************************************
+ * xenctl.h
+ *
+ * Xen userspace control interfaces
+ *
+ * Copyright (c) 2002-2004, K A Fraser, B Dragovic
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation; or, when distributed
+ * separately from the Linux kernel or incorporated into other
+ * software packages, subject to the following license:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this source file (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+/*
+ * capabilities.c
+ */
+int capabilities_create_proc_entry(void);
+void capabilities_remove_proc_entry(void);
--
1.5.4.1
linux-2.6-0051-xen-Add-proc-xen-privcmd.patch:
--- NEW FILE linux-2.6-0051-xen-Add-proc-xen-privcmd.patch ---
>From 2148d579f8673c6cb4cd66110d0105543c22157d Mon Sep 17 00:00:00 2001
From: Mark McLoughlin <markmc redhat com>
Date: Mon, 4 Feb 2008 08:24:57 +0000
Subject: [PATCH] xen: Add /proc/xen/privcmd
/proc/xen/privcmd is an ioctl() interface which allows
userspace apps to invoke hypercalls.
There should also be an ioctl (IOCTL_PRIVCMD_MMAP)
which is used to map foreign pages into a processes
address space, but we leave this unimplemented for
now pending further work on foreign page support.
Signed-off-by: Mark McLoughlin <markmc redhat com>
---
drivers/xen/xenctrl/Makefile | 1 +
drivers/xen/xenctrl/main.c | 6 +++
drivers/xen/xenctrl/privcmd.c | 88 +++++++++++++++++++++++++++++++++++++++
drivers/xen/xenctrl/xenctrl.h | 6 +++
include/asm-x86/xen/hypercall.h | 28 ++++++++++++
include/xen/sys/privcmd.h | 79 +++++++++++++++++++++++++++++++++++
6 files changed, 208 insertions(+), 0 deletions(-)
create mode 100644 drivers/xen/xenctrl/privcmd.c
create mode 100644 include/xen/sys/privcmd.h
diff --git a/drivers/xen/xenctrl/Makefile b/drivers/xen/xenctrl/Makefile
index 631f535..8a706cb 100644
--- a/drivers/xen/xenctrl/Makefile
+++ b/drivers/xen/xenctrl/Makefile
@@ -3,3 +3,4 @@ obj-$(CONFIG_XENCTRL) += xenctrl.o
xenctrl-objs =
xenctrl-objs += main.o
xenctrl-objs += capabilities.o
+xenctrl-objs += privcmd.o
diff --git a/drivers/xen/xenctrl/main.c b/drivers/xen/xenctrl/main.c
index 0e42f7e..d1fe6ef 100644
--- a/drivers/xen/xenctrl/main.c
+++ b/drivers/xen/xenctrl/main.c
@@ -55,14 +55,20 @@ static int __init xenctrl_init(void)
if (ret)
goto fail1;
+ ret = privcmd_create_proc_entry();
+ if (ret)
+ goto fail2;
+
return 0;
+ fail2: capabilities_remove_proc_entry();
fail1: remove_proc_entry("xen", NULL);
return ret;
}
static void __exit xenctrl_exit(void)
{
+ privcmd_remove_proc_entry();
capabilities_remove_proc_entry();
remove_proc_entry("xen", NULL);
}
diff --git a/drivers/xen/xenctrl/privcmd.c b/drivers/xen/xenctrl/privcmd.c
new file mode 100644
index 0000000..1746a17
--- /dev/null
+++ b/drivers/xen/xenctrl/privcmd.c
@@ -0,0 +1,88 @@
+/******************************************************************************
+ * privcmd.c
+ *
+ * Interface to privileged domain-0 commands.
+ *
+ * Copyright (c) 2002-2004, K A Fraser, B Dragovic
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation; or, when distributed
+ * separately from the Linux kernel or incorporated into other
+ * software packages, subject to the following license:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this source file (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <linux/proc_fs.h>
+#include <linux/module.h>
+#include <linux/uaccess.h>
+#include <asm/xen/hypervisor.h>
+#include <xen/sys/privcmd.h>
+
+static long privcmd_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ int ret = -ENOSYS;
+
+ switch (cmd) {
+ case IOCTL_PRIVCMD_HYPERCALL: {
+ privcmd_hypercall_t hypercall;
+
+ if (copy_from_user(&hypercall, (void __user *)arg,
+ sizeof(hypercall)))
+ return -EFAULT;
+
+ ret = privcmd_hypercall(&hypercall);
+ break;
+ }
+
+ case IOCTL_PRIVCMD_MMAP:
+ case IOCTL_PRIVCMD_MMAPBATCH:
+ printk(KERN_WARNING "IOCTL_PRIVCMD_MMAP ioctl not yet implemented\n");
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+static const struct file_operations privcmd_file_ops = {
+ .unlocked_ioctl = privcmd_ioctl,
+};
+
+int privcmd_create_proc_entry(void)
+{
+ static struct proc_dir_entry *entry;
+
+ entry = create_proc_entry("xen/privcmd", 0400, NULL);
+ if (!entry)
+ return -ENOMEM;
+
+ entry->owner = THIS_MODULE;
+ entry->proc_fops = &privcmd_file_ops;
+
+ return 0;
+}
+
+void privcmd_remove_proc_entry(void)
+{
+ remove_proc_entry("xen/privcmd", NULL);
+}
diff --git a/drivers/xen/xenctrl/xenctrl.h b/drivers/xen/xenctrl/xenctrl.h
index e90e588..e88ada5 100644
--- a/drivers/xen/xenctrl/xenctrl.h
+++ b/drivers/xen/xenctrl/xenctrl.h
@@ -35,3 +35,9 @@
*/
int capabilities_create_proc_entry(void);
void capabilities_remove_proc_entry(void);
+
+/*
+ * privcmd.c
+ */
+int privcmd_create_proc_entry(void);
+void privcmd_remove_proc_entry(void);
diff --git a/include/asm-x86/xen/hypercall.h b/include/asm-x86/xen/hypercall.h
index 0802755..47b61f8 100644
--- a/include/asm-x86/xen/hypercall.h
+++ b/include/asm-x86/xen/hypercall.h
@@ -419,4 +419,32 @@ MULTI_stack_switch(struct multicall_entry *mcl,
mcl->args[1] = esp;
}
+#include <xen/sys/privcmd.h>
+
+static inline int privcmd_hypercall(privcmd_hypercall_t *hypercall)
+{
+ int ret;
+
+ if (hypercall->op >= (PAGE_SIZE >> 5))
+ return -EINVAL;
+
+ __asm__ __volatile__ (
+ "pushl %%ebx; pushl %%ecx; pushl %%edx; "
+ "pushl %%esi; pushl %%edi; "
+ "movl 8(%%eax),%%ebx ;"
+ "movl 16(%%eax),%%ecx ;"
+ "movl 24(%%eax),%%edx ;"
+ "movl 32(%%eax),%%esi ;"
+ "movl 40(%%eax),%%edi ;"
+ "movl (%%eax),%%eax ;"
+ "shll $5,%%eax ;"
+ "addl $hypercall_page,%%eax ;"
+ "call *%%eax ;"
+ "popl %%edi; popl %%esi; popl %%edx; "
+ "popl %%ecx; popl %%ebx"
+ : "=a" (ret) : "0" (hypercall) : "memory" );
+
+ return ret;
+}
+
#endif /* __HYPERCALL_H__ */
diff --git a/include/xen/sys/privcmd.h b/include/xen/sys/privcmd.h
new file mode 100644
index 0000000..9cfa9d7
--- /dev/null
+++ b/include/xen/sys/privcmd.h
@@ -0,0 +1,79 @@
+/******************************************************************************
+ * privcmd.h
+ *
+ * Interface to /proc/xen/privcmd.
+ *
+ * Copyright (c) 2003-2005, K A Fraser
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation; or, when distributed
+ * separately from the Linux kernel or incorporated into other
+ * software packages, subject to the following license:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this source file (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef __LINUX_PUBLIC_PRIVCMD_H__
+#define __LINUX_PUBLIC_PRIVCMD_H__
+
+#include <linux/types.h>
+
+#ifndef __user
+#define __user
+#endif
+
+typedef struct privcmd_hypercall
+{
+ __u64 op;
+ __u64 arg[5];
+} privcmd_hypercall_t;
+
+typedef struct privcmd_mmap_entry {
+ __u64 va;
+ __u64 mfn;
+ __u64 npages;
+} privcmd_mmap_entry_t;
+
+typedef struct privcmd_mmap {
+ int num;
+ domid_t dom; /* target domain */
+ privcmd_mmap_entry_t __user *entry;
+} privcmd_mmap_t;
+
+typedef struct privcmd_mmapbatch {
+ int num; /* number of pages to populate */
+ domid_t dom; /* target domain */
+ __u64 addr; /* virtual address */
+ ulong __user *arr; /* array of mfns - top nibble set on err */
+} privcmd_mmapbatch_t;
+
+/*
+ * @cmd: IOCTL_PRIVCMD_HYPERCALL
+ * @arg: &privcmd_hypercall_t
+ * Return: Value returned from execution of the specified hypercall.
+ */
+#define IOCTL_PRIVCMD_HYPERCALL \
+ _IOC(_IOC_NONE, 'P', 0, sizeof(privcmd_hypercall_t))
+#define IOCTL_PRIVCMD_MMAP \
+ _IOC(_IOC_NONE, 'P', 2, sizeof(privcmd_mmap_t))
+#define IOCTL_PRIVCMD_MMAPBATCH \
+ _IOC(_IOC_NONE, 'P', 3, sizeof(privcmd_mmapbatch_t))
+
+#endif /* __LINUX_PUBLIC_PRIVCMD_H__ */
--
1.5.4.1
linux-2.6-0052-xen-dom0-Add-proc-xen-xsd_-port-kva.patch:
--- NEW FILE linux-2.6-0052-xen-dom0-Add-proc-xen-xsd_-port-kva.patch ---
>From 859171fe39c21fbff963c9fb9afa1996e9dcc942 Mon Sep 17 00:00:00 2001
From: Mark McLoughlin <markmc redhat com>
Date: Mon, 4 Feb 2008 10:29:28 +0000
Subject: [PATCH] xen dom0: Add /proc/xen/xsd_{port,kva}
These two /proc interfaces allows xenstored to make
itself available to the Dom0 kernel by mapping the
"interface" page, and connecting to the event
channel, allocated by the kernel.
Signed-off-by: Mark McLoughlin <markmc redhat com>
---
drivers/xen/xenbus/xenbus_comms.h | 2 -
drivers/xen/xenbus/xenbus_probe.c | 5 +-
drivers/xen/xenctrl/Makefile | 1 +
drivers/xen/xenctrl/main.c | 6 ++
drivers/xen/xenctrl/xenctrl.h | 6 ++
drivers/xen/xenctrl/xenstore.c | 118 +++++++++++++++++++++++++++++++++++++
include/xen/xenbus.h | 4 +
7 files changed, 139 insertions(+), 3 deletions(-)
create mode 100644 drivers/xen/xenctrl/xenstore.c
diff --git a/drivers/xen/xenbus/xenbus_comms.h b/drivers/xen/xenbus/xenbus_comms.h
index c21db75..cb5324f 100644
--- a/drivers/xen/xenbus/xenbus_comms.h
+++ b/drivers/xen/xenbus/xenbus_comms.h
@@ -40,7 +40,5 @@ int xb_read(void *data, unsigned len);
int xb_data_to_read(void);
int xb_wait_for_data_to_read(void);
int xs_input_avail(void);
-extern struct xenstore_domain_interface *xen_store_interface;
-extern int xen_store_evtchn;
#endif /* _XENBUS_COMMS_H */
diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c
index 1531adf..290e993 100644
--- a/drivers/xen/xenbus/xenbus_probe.c
+++ b/drivers/xen/xenbus/xenbus_probe.c
@@ -56,8 +56,11 @@
#include "xenbus_probe.h"
int xen_store_evtchn;
+EXPORT_SYMBOL_GPL(xen_store_evtchn);
+unsigned long xen_store_mfn;
+EXPORT_SYMBOL_GPL(xen_store_mfn);
struct xenstore_domain_interface *xen_store_interface;
-static unsigned long xen_store_mfn;
+EXPORT_SYMBOL_GPL(xen_store_interface);
static BLOCKING_NOTIFIER_HEAD(xenstore_chain);
diff --git a/drivers/xen/xenctrl/Makefile b/drivers/xen/xenctrl/Makefile
index 8a706cb..4416174 100644
--- a/drivers/xen/xenctrl/Makefile
+++ b/drivers/xen/xenctrl/Makefile
@@ -4,3 +4,4 @@ xenctrl-objs =
xenctrl-objs += main.o
xenctrl-objs += capabilities.o
xenctrl-objs += privcmd.o
+xenctrl-objs += xenstore.o
diff --git a/drivers/xen/xenctrl/main.c b/drivers/xen/xenctrl/main.c
index d1fe6ef..2ebf85a 100644
--- a/drivers/xen/xenctrl/main.c
+++ b/drivers/xen/xenctrl/main.c
@@ -59,8 +59,13 @@ static int __init xenctrl_init(void)
if (ret)
goto fail2;
+ ret = xsd_create_proc_entry();
+ if (ret)
+ goto fail3;
+
return 0;
+ fail3: privcmd_remove_proc_entry();
fail2: capabilities_remove_proc_entry();
fail1: remove_proc_entry("xen", NULL);
return ret;
@@ -68,6 +73,7 @@ static int __init xenctrl_init(void)
static void __exit xenctrl_exit(void)
{
+ xsd_remove_proc_entry();
privcmd_remove_proc_entry();
capabilities_remove_proc_entry();
remove_proc_entry("xen", NULL);
diff --git a/drivers/xen/xenctrl/xenctrl.h b/drivers/xen/xenctrl/xenctrl.h
index e88ada5..0e8f8cf 100644
--- a/drivers/xen/xenctrl/xenctrl.h
+++ b/drivers/xen/xenctrl/xenctrl.h
@@ -41,3 +41,9 @@ void capabilities_remove_proc_entry(void);
*/
int privcmd_create_proc_entry(void);
void privcmd_remove_proc_entry(void);
+
+/*
+ * xenstore.c
+ */
+int xsd_create_proc_entry(void);
+void xsd_remove_proc_entry(void);
diff --git a/drivers/xen/xenctrl/xenstore.c b/drivers/xen/xenctrl/xenstore.c
new file mode 100644
index 0000000..4b38ff5
--- /dev/null
+++ b/drivers/xen/xenctrl/xenstore.c
@@ -0,0 +1,118 @@
+/******************************************************************************
+ * xenstore.c
+ *
+ * /proc/xen/xsd_{port,kva}
+ *
+ * Copyright (C) 2005 Rusty Russell, IBM Corporation
+ * Copyright (C) 2005 Mike Wray, Hewlett-Packard
+ * Copyright (C) 2005, 2006 XenSource Ltd
+ * Copyright (C) 2007 Solarflare Communications, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation; or, when distributed
+ * separately from the Linux kernel or incorporated into other
+ * software packages, subject to the following license:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this source file (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <asm/xen/hypervisor.h>
+#include <xen/page.h>
+#include <xen/xenbus.h>
+
+static int xsd_kva_mmap(struct file *file, struct vm_area_struct *vma)
+{
+ size_t size = vma->vm_end - vma->vm_start;
+
+ if ((size > PAGE_SIZE) || (vma->vm_pgoff != 0))
+ return -EINVAL;
+
+ if (remap_pfn_range(vma, vma->vm_start, mfn_to_pfn(xen_store_mfn),
+ size, vma->vm_page_prot))
+ return -EAGAIN;
+
+ return 0;
+}
+
+static int xsd_kva_show(struct seq_file *m, void *v)
+{
+ seq_printf(m, "0x%p\n", xen_store_interface);
+ return 0;
+}
+
+static int xsd_kva_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, xsd_kva_show, NULL);
+}
+
+static const struct file_operations xsd_kva_fops = {
+ .open = xsd_kva_open,
+ .mmap = xsd_kva_mmap,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static int xsd_port_read(char *page, char **start, off_t off,
+ int count, int *eof, void *data)
+{
+ int len;
+
+ len = sprintf(page, "%d\n", xen_store_evtchn);
+ *eof = 1;
+ return len;
+}
+
+int xsd_create_proc_entry(void)
+{
+ struct proc_dir_entry *entry;
+
+ if (!is_initial_xendomain())
+ return 0;
+
+ entry = create_proc_entry("xen/xsd_kva", 0600, NULL);
+ if (!entry)
+ return -ENOMEM;
+
+ entry->owner = THIS_MODULE;
+ entry->proc_fops = &xsd_kva_fops;
+
+ entry = create_proc_entry("xen/xsd_port", 0400, NULL);
+ if (!entry)
+ goto fail;
+
+ entry->owner = THIS_MODULE;
+ entry->read_proc = xsd_port_read;
+
+ return 0;
+
+ fail: remove_proc_entry("xen/xsd_kva", NULL);
+ return - ENOMEM;
+}
+
+void xsd_remove_proc_entry(void)
+{
+ remove_proc_entry("xen/xsd_port", NULL);
+ remove_proc_entry("xen/xsd_kva", NULL);
+}
diff --git a/include/xen/xenbus.h b/include/xen/xenbus.h
index 6f7c290..40e0083 100644
--- a/include/xen/xenbus.h
+++ b/include/xen/xenbus.h
@@ -231,4 +231,8 @@ const char *xenbus_strstate(enum xenbus_state state);
int xenbus_dev_is_online(struct xenbus_device *dev);
int xenbus_frontend_closed(struct xenbus_device *dev);
+extern int xen_store_evtchn;
+extern unsigned long xen_store_mfn;
+extern struct xenstore_domain_interface *xen_store_interface;
+
#endif /* _XEN_XENBUS_H */
--
1.5.4.1
linux-2.6-0053-xen-Add-proc-xen-xenbus.patch:
--- NEW FILE linux-2.6-0053-xen-Add-proc-xen-xenbus.patch ---
>From 3d5825ae92d8c5b59448a51d818c4b049b414e4f Mon Sep 17 00:00:00 2001
From: Mark McLoughlin <markmc redhat com>
Date: Mon, 4 Feb 2008 22:04:36 +0000
Subject: [PATCH] xen: Add /proc/xen/xenbus
This interface is used by userspace programs to talk to
xenstored.
Since xenstored makes itself available to Dom0 userspace
via a socket this should only really be useful in Domu,
but it turns out that Dom0 apps historically default
to using /proc/xen/xenbus rather than the socket.
Signed-off-by: Mark McLoughlin <markmc redhat com>
---
drivers/xen/xenbus/xenbus_xs.c | 1 +
drivers/xen/xenctrl/Makefile | 1 +
drivers/xen/xenctrl/main.c | 6 +
drivers/xen/xenctrl/xenbus.c | 398 ++++++++++++++++++++++++++++++++++++++++
drivers/xen/xenctrl/xenctrl.h | 6 +
5 files changed, 412 insertions(+), 0 deletions(-)
create mode 100644 drivers/xen/xenctrl/xenbus.c
diff --git a/drivers/xen/xenbus/xenbus_xs.c b/drivers/xen/xenbus/xenbus_xs.c
index 227d53b..810e24a 100644
--- a/drivers/xen/xenbus/xenbus_xs.c
+++ b/drivers/xen/xenbus/xenbus_xs.c
@@ -184,6 +184,7 @@ void *xenbus_dev_request_and_reply(struct xsd_sockmsg *msg)
return ret;
}
+EXPORT_SYMBOL(xenbus_dev_request_and_reply);
/* Send message to xs, get kmalloc'ed reply. ERR_PTR() on error. */
static void *xs_talkv(struct xenbus_transaction t,
diff --git a/drivers/xen/xenctrl/Makefile b/drivers/xen/xenctrl/Makefile
index 4416174..959b0eb 100644
--- a/drivers/xen/xenctrl/Makefile
+++ b/drivers/xen/xenctrl/Makefile
@@ -5,3 +5,4 @@ xenctrl-objs += main.o
xenctrl-objs += capabilities.o
xenctrl-objs += privcmd.o
xenctrl-objs += xenstore.o
+xenctrl-objs += xenbus.o
diff --git a/drivers/xen/xenctrl/main.c b/drivers/xen/xenctrl/main.c
index 2ebf85a..95e1b3b 100644
--- a/drivers/xen/xenctrl/main.c
+++ b/drivers/xen/xenctrl/main.c
@@ -63,8 +63,13 @@ static int __init xenctrl_init(void)
if (ret)
goto fail3;
+ ret = xenbus_create_proc_entry();
+ if (ret)
+ goto fail4;
+
return 0;
+ fail4: xsd_remove_proc_entry();
fail3: privcmd_remove_proc_entry();
fail2: capabilities_remove_proc_entry();
fail1: remove_proc_entry("xen", NULL);
@@ -73,6 +78,7 @@ static int __init xenctrl_init(void)
static void __exit xenctrl_exit(void)
{
+ xenbus_remove_proc_entry();
xsd_remove_proc_entry();
privcmd_remove_proc_entry();
capabilities_remove_proc_entry();
diff --git a/drivers/xen/xenctrl/xenbus.c b/drivers/xen/xenctrl/xenbus.c
new file mode 100644
index 0000000..8127dc8
--- /dev/null
+++ b/drivers/xen/xenctrl/xenbus.c
@@ -0,0 +1,398 @@
+/*
+ * xenbus.c
+ *
+ * /proc/xen/xenbus gives user-space access to the kernel's xenbus
+ * connection to xenstore.
+ *
+ * Copyright (c) 2005, Christian Limpach
+ * Copyright (c) 2005, Rusty Russell, IBM Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation; or, when distributed
+ * separately from the Linux kernel or incorporated into other
+ * software packages, subject to the following license:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this source file (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <linux/proc_fs.h>
+#include <linux/module.h>
+#include <linux/uaccess.h>
+#include <linux/poll.h>
+
+#include <xen/xenbus.h>
+
+struct xenbus_dev_transaction {
+ struct list_head list;
+ struct xenbus_transaction handle;
+};
+
+struct read_buffer {
+ struct list_head list;
+ unsigned int cons;
+ unsigned int len;
+ char msg[];
+};
+
+struct xenbus_dev_data {
+ /* In-progress transaction. */
+ struct list_head transactions;
+
+ /* Active watches. */
+ struct list_head watches;
+
+ /* Partial request. */
+ unsigned int len;
+ union {
+ struct xsd_sockmsg msg;
+ char buffer[PAGE_SIZE];
+ } u;
+
+ /* Response queue. */
+ struct list_head read_buffers;
+ wait_queue_head_t read_waitq;
+
+ struct mutex reply_mutex;
+};
+
+static ssize_t xenbus_dev_read(struct file *filp,
+ char __user *ubuf,
+ size_t len, loff_t *ppos)
+{
+ struct xenbus_dev_data *u = filp->private_data;
+ struct read_buffer *rb;
+ int i, ret;
+
+ mutex_lock(&u->reply_mutex);
+ while (list_empty(&u->read_buffers)) {
+ mutex_unlock(&u->reply_mutex);
+ ret = wait_event_interruptible(u->read_waitq,
+ !list_empty(&u->read_buffers));
+ if (ret)
+ return ret;
+ mutex_lock(&u->reply_mutex);
+ }
+
+ rb = list_entry(u->read_buffers.next, struct read_buffer, list);
+ for (i = 0; i < len;) {
+ put_user(rb->msg[rb->cons], ubuf + i);
+ i++;
+ rb->cons++;
+ if (rb->cons == rb->len) {
+ list_del(&rb->list);
+ kfree(rb);
+ if (list_empty(&u->read_buffers))
+ break;
+ rb = list_entry(u->read_buffers.next,
+ struct read_buffer, list);
+ }
+ }
+ mutex_unlock(&u->reply_mutex);
+
+ return i;
+}
+
+static void queue_reply(struct xenbus_dev_data *u,
+ char *data, unsigned int len)
+{
+ struct read_buffer *rb;
+
+ if (len == 0)
+ return;
+
+ rb = kmalloc(sizeof(*rb) + len, GFP_KERNEL);
+ BUG_ON(rb == NULL);
+
+ rb->cons = 0;
+ rb->len = len;
+
+ memcpy(rb->msg, data, len);
+
+ list_add_tail(&rb->list, &u->read_buffers);
+
+ wake_up(&u->read_waitq);
+}
+
+struct watch_adapter
+{
+ struct list_head list;
+ struct xenbus_watch watch;
+ struct xenbus_dev_data *dev_data;
+ char *token;
+};
+
+static void free_watch_adapter(struct watch_adapter *watch)
+{
+ kfree(watch->watch.node);
+ kfree(watch->token);
+ kfree(watch);
+}
+
+static void watch_fired(struct xenbus_watch *watch,
+ const char **vec,
+ unsigned int len)
+{
+ struct watch_adapter *adap =
+ container_of(watch, struct watch_adapter, watch);
+ struct xsd_sockmsg hdr;
+ const char *path, *token;
+ int path_len, tok_len, body_len;
+
+ path = vec[XS_WATCH_PATH];
+ token = adap->token;
+
+ path_len = strlen(path) + 1;
+ tok_len = strlen(token) + 1;
+ body_len = path_len + tok_len;
+
+ hdr.type = XS_WATCH_EVENT;
+ hdr.len = body_len;
+
+ mutex_lock(&adap->dev_data->reply_mutex);
+ queue_reply(adap->dev_data, (char *)&hdr, sizeof(hdr));
+ queue_reply(adap->dev_data, (char *)path, path_len);
+ queue_reply(adap->dev_data, (char *)token, tok_len);
+ mutex_unlock(&adap->dev_data->reply_mutex);
+}
+
+static LIST_HEAD(watch_list);
+
+static ssize_t xenbus_dev_write(struct file *filp,
+ const char __user *ubuf,
+ size_t len, loff_t *ppos)
+{
+ struct xenbus_dev_data *u = filp->private_data;
+ struct xenbus_dev_transaction *trans = NULL;
+ uint32_t msg_type;
+ void *reply;
+ char *path, *token;
+ struct watch_adapter *watch, *tmp_watch;
+ int err, rc = len;
+
+ if ((len + u->len) > sizeof(u->u.buffer)) {
+ rc = -EINVAL;
+ goto out;
+ }
+
+ if (copy_from_user(u->u.buffer + u->len, ubuf, len) != 0) {
+ rc = -EFAULT;
+ goto out;
+ }
+
+ u->len += len;
+ if ((u->len < sizeof(u->u.msg)) ||
+ (u->len < (sizeof(u->u.msg) + u->u.msg.len)))
+ return rc;
+
+ msg_type = u->u.msg.type;
+
+ switch (msg_type) {
+ case XS_TRANSACTION_START:
+ case XS_TRANSACTION_END:
+ case XS_DIRECTORY:
+ case XS_READ:
+ case XS_GET_PERMS:
+ case XS_RELEASE:
+ case XS_GET_DOMAIN_PATH:
+ case XS_WRITE:
+ case XS_MKDIR:
+ case XS_RM:
+ case XS_SET_PERMS:
+ if (msg_type == XS_TRANSACTION_START) {
+ trans = kmalloc(sizeof(*trans), GFP_KERNEL);
+ if (!trans) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ }
+
+ reply = xenbus_dev_request_and_reply(&u->u.msg);
+ if (IS_ERR(reply)) {
+ kfree(trans);
+ rc = PTR_ERR(reply);
+ goto out;
+ }
+
+ if (msg_type == XS_TRANSACTION_START) {
+ trans->handle.id = simple_strtoul(reply, NULL, 0);
+ list_add(&trans->list, &u->transactions);
+ } else if (msg_type == XS_TRANSACTION_END) {
+ list_for_each_entry(trans, &u->transactions, list)
+ if (trans->handle.id == u->u.msg.tx_id)
+ break;
+ BUG_ON(&trans->list == &u->transactions);
+ list_del(&trans->list);
+ kfree(trans);
+ }
+ mutex_lock(&u->reply_mutex);
+ queue_reply(u, (char *)&u->u.msg, sizeof(u->u.msg));
+ queue_reply(u, (char *)reply, u->u.msg.len);
+ mutex_unlock(&u->reply_mutex);
+ kfree(reply);
+ break;
+
+ case XS_WATCH:
+ case XS_UNWATCH: {
+ static const char *XS_RESP = "OK";
+ struct xsd_sockmsg hdr;
+
+ path = u->u.buffer + sizeof(u->u.msg);
+ token = memchr(path, 0, u->u.msg.len);
+ if (token == NULL) {
+ rc = -EILSEQ;
+ goto out;
+ }
+ token++;
+
+ if (msg_type == XS_WATCH) {
+ watch = kmalloc(sizeof(*watch), GFP_KERNEL);
+ watch->watch.node = kmalloc(strlen(path)+1,
+ GFP_KERNEL);
+ strcpy((char *)watch->watch.node, path);
+ watch->watch.callback = watch_fired;
+ watch->token = kmalloc(strlen(token)+1, GFP_KERNEL);
+ strcpy(watch->token, token);
+ watch->dev_data = u;
+
+ err = register_xenbus_watch(&watch->watch);
+ if (err) {
+ free_watch_adapter(watch);
+ rc = err;
+ goto out;
+ }
+
+ list_add(&watch->list, &u->watches);
+ } else {
+ list_for_each_entry_safe(watch, tmp_watch,
+ &u->watches, list) {
+ if (!strcmp(watch->token, token) &&
+ !strcmp(watch->watch.node, path))
+ {
+ unregister_xenbus_watch(&watch->watch);
+ list_del(&watch->list);
+ free_watch_adapter(watch);
+ break;
+ }
+ }
+ }
+
+ hdr.type = msg_type;
+ hdr.len = strlen(XS_RESP) + 1;
+ mutex_lock(&u->reply_mutex);
+ queue_reply(u, (char *)&hdr, sizeof(hdr));
+ queue_reply(u, (char *)XS_RESP, hdr.len);
+ mutex_unlock(&u->reply_mutex);
+ break;
+ }
+
+ default:
+ rc = -EINVAL;
+ break;
+ }
+
+ out:
+ u->len = 0;
+ return rc;
+}
+
+static int xenbus_dev_open(struct inode *inode, struct file *filp)
+{
+ struct xenbus_dev_data *u;
+
+ if (xen_store_evtchn == 0)
+ return -ENOENT;
+
+ nonseekable_open(inode, filp);
+
+ u = kzalloc(sizeof(*u), GFP_KERNEL);
+ if (u == NULL)
+ return -ENOMEM;
+
+ INIT_LIST_HEAD(&u->transactions);
+ INIT_LIST_HEAD(&u->watches);
+ INIT_LIST_HEAD(&u->read_buffers);
+ init_waitqueue_head(&u->read_waitq);
+
+ mutex_init(&u->reply_mutex);
+
+ filp->private_data = u;
+
+ return 0;
+}
+
+static int xenbus_dev_release(struct inode *inode, struct file *filp)
+{
+ struct xenbus_dev_data *u = filp->private_data;
+ struct xenbus_dev_transaction *trans, *tmp;
+ struct watch_adapter *watch, *tmp_watch;
+
+ list_for_each_entry_safe(trans, tmp, &u->transactions, list) {
+ xenbus_transaction_end(trans->handle, 1);
+ list_del(&trans->list);
+ kfree(trans);
+ }
+
+ list_for_each_entry_safe(watch, tmp_watch, &u->watches, list) {
+ unregister_xenbus_watch(&watch->watch);
+ list_del(&watch->list);
+ free_watch_adapter(watch);
+ }
+
+ kfree(u);
+
+ return 0;
+}
+
+static unsigned int xenbus_dev_poll(struct file *file, poll_table *wait)
+{
+ struct xenbus_dev_data *u = file->private_data;
+
+ poll_wait(file, &u->read_waitq, wait);
+ if (!list_empty(&u->read_buffers))
+ return POLLIN | POLLRDNORM;
+ return 0;
+}
+
+static const struct file_operations xenbus_dev_file_ops = {
+ .read = xenbus_dev_read,
+ .write = xenbus_dev_write,
+ .open = xenbus_dev_open,
+ .release = xenbus_dev_release,
+ .poll = xenbus_dev_poll,
+};
+
+int xenbus_create_proc_entry(void)
+{
+ struct proc_dir_entry *entry;
+
+ entry = create_proc_entry("xen/xenbus", 0400, NULL);
+ if (!entry)
+ return -ENOMEM;
+
+ entry->owner = THIS_MODULE;
+ entry->proc_fops = &xenbus_dev_file_ops;
+
+ return 0;
+}
+
+void xenbus_remove_proc_entry(void)
+{
+ remove_proc_entry("xen/xenbus", NULL);
+}
diff --git a/drivers/xen/xenctrl/xenctrl.h b/drivers/xen/xenctrl/xenctrl.h
index 0e8f8cf..5990be5 100644
--- a/drivers/xen/xenctrl/xenctrl.h
+++ b/drivers/xen/xenctrl/xenctrl.h
@@ -47,3 +47,9 @@ void privcmd_remove_proc_entry(void);
*/
int xsd_create_proc_entry(void);
void xsd_remove_proc_entry(void);
+
+/*
+ * xenbus.c
+ */
+int xenbus_create_proc_entry(void);
+void xenbus_remove_proc_entry(void);
--
1.5.4.1
linux-2.6-0054-xen-Add-dev-xen-evtchn.patch:
--- NEW FILE linux-2.6-0054-xen-Add-dev-xen-evtchn.patch ---
>From 6c6205cc795e06cbfc9bad5d54ce4dbb3984de95 Mon Sep 17 00:00:00 2001
From: Mark McLoughlin <markmc redhat com>
Date: Mon, 4 Feb 2008 08:25:31 +0000
Subject: [PATCH] xen: Add /dev/xen/evtchn
This device driver allows userspace programs to allocate
event channels, bind to existing channels, poll for
pending events etc.
An additional kernel interface is provided to allow the
driver to register a handler for event upcalls.
Signed-off-by: Mark McLoughlin <markmc redhat com>
---
arch/x86/xen/events.c | 31 ++-
drivers/xen/xenctrl/Makefile | 1 +
drivers/xen/xenctrl/evtchn.c | 552 +++++++++++++++++++++++++++++++++++++++++
drivers/xen/xenctrl/main.c | 6 +
drivers/xen/xenctrl/xenctrl.h | 6 +
include/xen/events.h | 11 +
include/xen/sys/evtchn.h | 88 +++++++
7 files changed, 691 insertions(+), 4 deletions(-)
create mode 100644 drivers/xen/xenctrl/evtchn.c
create mode 100644 include/xen/sys/evtchn.h
diff --git a/arch/x86/xen/events.c b/arch/x86/xen/events.c
index ca4912e..abce636 100644
--- a/arch/x86/xen/events.c
+++ b/arch/x86/xen/events.c
@@ -169,11 +169,12 @@ static inline unsigned int cpu_from_evtchn(unsigned int evtchn)
return cpu_evtchn[evtchn];
}
-static inline void clear_evtchn(int port)
+void clear_evtchn(int port)
{
struct shared_info *s = HYPERVISOR_shared_info;
sync_clear_bit(port, &s->evtchn_pending[0]);
}
+EXPORT_SYMBOL_GPL(clear_evtchn);
static inline void set_evtchn(int port)
{
@@ -199,13 +200,14 @@ void notify_remote_via_irq(int irq)
}
EXPORT_SYMBOL_GPL(notify_remote_via_irq);
-static void mask_evtchn(int port)
+void mask_evtchn(int port)
{
struct shared_info *s = HYPERVISOR_shared_info;
sync_set_bit(port, &s->evtchn_mask[0]);
}
+EXPORT_SYMBOL_GPL(mask_evtchn);
-static void unmask_evtchn(int port)
+void unmask_evtchn(int port)
{
struct shared_info *s = HYPERVISOR_shared_info;
unsigned int cpu = get_cpu();
@@ -234,6 +236,7 @@ static void unmask_evtchn(int port)
put_cpu();
}
+EXPORT_SYMBOL_GPL(unmask_evtchn);
static int find_unbound_irq(void)
{
@@ -463,6 +466,22 @@ void xen_send_IPI_one(unsigned int cpu, enum ipi_vector vector)
notify_remote_via_irq(irq);
}
+/*
+ * Notifier list for event channels not bound to an irq
+ */
+static ATOMIC_NOTIFIER_HEAD(evtchn_upcall_notifier);
+
+int register_evtchn_upcall_notifier(struct notifier_block *n)
+{
+ return atomic_notifier_chain_register(&evtchn_upcall_notifier, n);
+}
+EXPORT_SYMBOL(register_evtchn_upcall_notifier);
+
+int unregister_evtchn_upcall_notifier(struct notifier_block *n)
+{
+ return atomic_notifier_chain_unregister(&evtchn_upcall_notifier, n);
+}
+EXPORT_SYMBOL(unregister_evtchn_upcall_notifier);
/*
* Search the CPUs pending events bitmasks. For each one found, map
@@ -503,6 +522,9 @@ fastcall void xen_evtchn_do_upcall(struct pt_regs *regs)
if (irq != -1) {
regs->orig_eax = ~irq;
do_IRQ(regs);
+ } else {
+ atomic_notifier_call_chain(&evtchn_upcall_notifier,
+ port, NULL);
}
}
}
@@ -515,7 +537,7 @@ fastcall void xen_evtchn_do_upcall(struct pt_regs *regs)
}
/* Rebind an evtchn so that it gets delivered to a specific cpu */
-static void rebind_irq_to_cpu(unsigned irq, unsigned tcpu)
+void rebind_irq_to_cpu(unsigned irq, unsigned tcpu)
{
struct evtchn_bind_vcpu bind_vcpu;
int evtchn = evtchn_from_irq(irq);
@@ -535,6 +557,7 @@ static void rebind_irq_to_cpu(unsigned irq, unsigned tcpu)
if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_vcpu, &bind_vcpu) >= 0)
bind_evtchn_to_cpu(evtchn, tcpu);
}
+EXPORT_SYMBOL_GPL(rebind_irq_to_cpu);
static void set_affinity_irq(unsigned irq, cpumask_t dest)
diff --git a/drivers/xen/xenctrl/Makefile b/drivers/xen/xenctrl/Makefile
index 959b0eb..efc12c2 100644
--- a/drivers/xen/xenctrl/Makefile
+++ b/drivers/xen/xenctrl/Makefile
@@ -6,3 +6,4 @@ xenctrl-objs += capabilities.o
xenctrl-objs += privcmd.o
xenctrl-objs += xenstore.o
xenctrl-objs += xenbus.o
+xenctrl-objs += evtchn.o
diff --git a/drivers/xen/xenctrl/evtchn.c b/drivers/xen/xenctrl/evtchn.c
new file mode 100644
index 0000000..22fabe2
--- /dev/null
+++ b/drivers/xen/xenctrl/evtchn.c
@@ -0,0 +1,552 @@
+/******************************************************************************
+ * evtchn.c
+ *
+ * Driver for receiving and demuxing event-channel signals.
+ *
+ * Copyright (c) 2004-2005, K A Fraser
+ * Multi-process extensions Copyright (c) 2004, Steven Smith
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation; or, when distributed
+ * separately from the Linux kernel or incorporated into other
+ * software packages, subject to the following license:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this source file (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <linux/fs.h>
+#include <linux/uaccess.h>
+#include <linux/poll.h>
+#include <linux/module.h>
+#include <linux/miscdevice.h>
+#include <linux/cpu.h>
+#include <asm/xen/hypervisor.h>
+#include <xen/events.h>
+#include <xen/sys/evtchn.h>
+
+struct per_user_data {
+ /* Notification ring, accessed via /dev/xen/evtchn. */
+#define EVTCHN_RING_SIZE (PAGE_SIZE / sizeof(evtchn_port_t))
+#define EVTCHN_RING_MASK(_i) ((_i)&(EVTCHN_RING_SIZE-1))
+ evtchn_port_t *ring;
+ unsigned int ring_cons, ring_prod, ring_overflow;
+ struct mutex ring_cons_mutex; /* protect against concurrent readers */
+
+ /* Processes wait on this queue when ring is empty. */
+ wait_queue_head_t evtchn_wait;
+ struct fasync_struct *evtchn_async_queue;
+
+ int bind_cpu;
+ int nr_event_wrong_delivery;
+};
+
+/* Who's bound to each port? */
+static struct per_user_data *port_user[NR_EVENT_CHANNELS];
+static spinlock_t port_user_lock;
+
+static int evtchn_upcall_callback(struct notifier_block *nb,
+ unsigned long port, void *v)
+{
+ struct per_user_data *u;
+ int ret = NOTIFY_OK;
+
+ spin_lock(&port_user_lock);
+
+ if (!(u = port_user[port]))
+ goto out;
+
+ ret = NOTIFY_STOP;
+
+ mask_evtchn(port);
+ clear_evtchn(port);
+
+ if ((u->ring_prod - u->ring_cons) >= EVTCHN_RING_SIZE) {
+ u->ring_overflow = 1;
+ goto out;
+ }
+
+ u->ring[EVTCHN_RING_MASK(u->ring_prod)] = port;
+ if (u->ring_cons != u->ring_prod++)
+ goto out;
+
+ wake_up_interruptible(&u->evtchn_wait);
+ kill_fasync(&u->evtchn_async_queue, SIGIO, POLL_IN);
+ out:
+ spin_unlock(&port_user_lock);
+ return ret;
+}
+
+static struct notifier_block evtchn_upcall_nfb = {
+ .notifier_call = evtchn_upcall_callback
+};
+
+static void evtchn_check_wrong_delivery(struct per_user_data *u)
+{
+ evtchn_port_t port;
+ unsigned int current_cpu = smp_processor_id();
+
+ /* Delivered to correct CPU? All is good. */
+ if (u->bind_cpu == current_cpu) {
+ u->nr_event_wrong_delivery = 0;
+ return;
+ }
+
+ /* Tolerate up to 100 consecutive misdeliveries. */
+ if (++u->nr_event_wrong_delivery < 100)
+ return;
+
+ spin_lock_irq(&port_user_lock);
+
+ for (port = 0; port < NR_EVENT_CHANNELS; port++)
+ if (port_user[port] == u)
+ rebind_irq_to_cpu(port, current_cpu);
+
+ u->bind_cpu = current_cpu;
+ u->nr_event_wrong_delivery = 0;
+
+ spin_unlock_irq(&port_user_lock);
+}
+
+static ssize_t evtchn_read(struct file *file, char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ int rc;
+ unsigned int c, p, bytes1 = 0, bytes2 = 0;
+ struct per_user_data *u = file->private_data;
+
+ /* Whole number of ports. */
+ count &= ~(sizeof(evtchn_port_t)-1);
+
+ if (count == 0)
+ return 0;
+
+ if (count > PAGE_SIZE)
+ count = PAGE_SIZE;
+
+ for (;;) {
+ mutex_lock(&u->ring_cons_mutex);
+
+ rc = -EFBIG;
+ if (u->ring_overflow)
+ goto unlock_out;
+
+ if ((c = u->ring_cons) != (p = u->ring_prod))
+ break;
+
+ mutex_unlock(&u->ring_cons_mutex);
+
+ if (file->f_flags & O_NONBLOCK)
+ return -EAGAIN;
+
+ rc = wait_event_interruptible(
+ u->evtchn_wait, u->ring_cons != u->ring_prod);
+ if (rc)
+ return rc;
+ }
+
+ /* Byte lengths of two chunks. Chunk split (if any) is at ring wrap. */
+ if (((c ^ p) & EVTCHN_RING_SIZE) != 0) {
+ bytes1 = (EVTCHN_RING_SIZE - EVTCHN_RING_MASK(c)) *
+ sizeof(evtchn_port_t);
+ bytes2 = EVTCHN_RING_MASK(p) * sizeof(evtchn_port_t);
+ } else {
+ bytes1 = (p - c) * sizeof(evtchn_port_t);
+ bytes2 = 0;
+ }
+
+ /* Truncate chunks according to caller's maximum byte count. */
+ if (bytes1 > count) {
+ bytes1 = count;
+ bytes2 = 0;
+ } else if ((bytes1 + bytes2) > count) {
+ bytes2 = count - bytes1;
+ }
+
+ rc = -EFAULT;
+ if (copy_to_user(buf, &u->ring[EVTCHN_RING_MASK(c)], bytes1) ||
+ ((bytes2 != 0) &&
+ copy_to_user(&buf[bytes1], &u->ring[0], bytes2)))
+ goto unlock_out;
+
+ evtchn_check_wrong_delivery(u);
+
+ u->ring_cons += (bytes1 + bytes2) / sizeof(evtchn_port_t);
+ rc = bytes1 + bytes2;
+
+ unlock_out:
+ mutex_unlock(&u->ring_cons_mutex);
+ return rc;
+}
+
+static ssize_t evtchn_write(struct file *file, const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ int rc, i;
+ evtchn_port_t *kbuf = (evtchn_port_t *)__get_free_page(GFP_KERNEL);
+ struct per_user_data *u = file->private_data;
+
+ if (kbuf == NULL)
+ return -ENOMEM;
+
+ /* Whole number of ports. */
+ count &= ~(sizeof(evtchn_port_t)-1);
+
+ rc = 0;
+ if (count == 0)
+ goto out;
+
+ if (count > PAGE_SIZE)
+ count = PAGE_SIZE;
+
+ rc = -EFAULT;
+ if (copy_from_user(kbuf, buf, count) != 0)
+ goto out;
+
+ spin_lock_irq(&port_user_lock);
+ for (i = 0; i < (count/sizeof(evtchn_port_t)); i++)
+ if ((kbuf[i] < NR_EVENT_CHANNELS) && (port_user[kbuf[i]] == u))
+ unmask_evtchn(kbuf[i]);
+ spin_unlock_irq(&port_user_lock);
+
+ rc = count;
+
+ out:
+ free_page((unsigned long)kbuf);
+ return rc;
+}
+
+static unsigned int next_bind_cpu(cpumask_t map)
+{
+ static unsigned int bind_cpu;
+ bind_cpu = next_cpu(bind_cpu, map);
+ if (bind_cpu >= NR_CPUS)
+ bind_cpu = first_cpu(map);
+ return bind_cpu;
+}
+
+static void evtchn_bind_to_user(struct per_user_data *u, int port)
+{
+ spin_lock_irq(&port_user_lock);
+
+ BUG_ON(port_user[port] != NULL);
+ port_user[port] = u;
+
+ if (u->bind_cpu == -1)
+ u->bind_cpu = next_bind_cpu(cpu_online_map);
+
+ rebind_irq_to_cpu(port, u->bind_cpu);
+
+ unmask_evtchn(port);
+
+ spin_unlock_irq(&port_user_lock);
+}
+
+static long evtchn_ioctl(struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ int rc;
+ struct per_user_data *u = file->private_data;
+ void __user *uarg = (void __user *) arg;
+
+ switch (cmd) {
+ case IOCTL_EVTCHN_BIND_VIRQ: {
+ struct ioctl_evtchn_bind_virq bind;
+ struct evtchn_bind_virq bind_virq;
+
+ rc = -EFAULT;
+ if (copy_from_user(&bind, uarg, sizeof(bind)))
+ break;
+
+ bind_virq.virq = bind.virq;
+ bind_virq.vcpu = 0;
+ rc = HYPERVISOR_event_channel_op(EVTCHNOP_bind_virq,
+ &bind_virq);
+ if (rc != 0)
+ break;
+
+ rc = bind_virq.port;
+ evtchn_bind_to_user(u, rc);
+ break;
+ }
+
+ case IOCTL_EVTCHN_BIND_INTERDOMAIN: {
+ struct ioctl_evtchn_bind_interdomain bind;
+ struct evtchn_bind_interdomain bind_interdomain;
+
+ rc = -EFAULT;
+ if (copy_from_user(&bind, uarg, sizeof(bind)))
+ break;
+
+ bind_interdomain.remote_dom = bind.remote_domain;
+ bind_interdomain.remote_port = bind.remote_port;
+ rc = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain,
+ &bind_interdomain);
+ if (rc != 0)
+ break;
+
+ rc = bind_interdomain.local_port;
+ evtchn_bind_to_user(u, rc);
+ break;
+ }
+
+ case IOCTL_EVTCHN_BIND_UNBOUND_PORT: {
+ struct ioctl_evtchn_bind_unbound_port bind;
+ struct evtchn_alloc_unbound alloc_unbound;
+
+ rc = -EFAULT;
+ if (copy_from_user(&bind, uarg, sizeof(bind)))
+ break;
+
+ alloc_unbound.dom = DOMID_SELF;
+ alloc_unbound.remote_dom = bind.remote_domain;
+ rc = HYPERVISOR_event_channel_op(EVTCHNOP_alloc_unbound,
+ &alloc_unbound);
+ if (rc != 0)
+ break;
+
+ rc = alloc_unbound.port;
+ evtchn_bind_to_user(u, rc);
+ break;
+ }
+
+ case IOCTL_EVTCHN_UNBIND: {
+ struct ioctl_evtchn_unbind unbind;
+ struct evtchn_close close;
+ int ret;
+
+ rc = -EFAULT;
+ if (copy_from_user(&unbind, uarg, sizeof(unbind)))
+ break;
+
+ rc = -EINVAL;
+ if (unbind.port >= NR_EVENT_CHANNELS)
+ break;
+
+ spin_lock_irq(&port_user_lock);
+
+ rc = -ENOTCONN;
+ if (port_user[unbind.port] != u) {
+ spin_unlock_irq(&port_user_lock);
+ break;
+ }
+
+ port_user[unbind.port] = NULL;
+ mask_evtchn(unbind.port);
+
+ spin_unlock_irq(&port_user_lock);
+
+ close.port = unbind.port;
+ ret = HYPERVISOR_event_channel_op(EVTCHNOP_close, &close);
+ BUG_ON(ret);
+
+ rc = 0;
+ break;
+ }
+
+ case IOCTL_EVTCHN_NOTIFY: {
+ struct ioctl_evtchn_notify notify;
+
+ rc = -EFAULT;
+ if (copy_from_user(¬ify, uarg, sizeof(notify)))
+ break;
+
+ if (notify.port >= NR_EVENT_CHANNELS) {
+ rc = -EINVAL;
+ } else if (port_user[notify.port] != u) {
+ rc = -ENOTCONN;
+ } else {
+ notify_remote_via_evtchn(notify.port);
+ rc = 0;
+ }
+ break;
+ }
+
+ case IOCTL_EVTCHN_RESET: {
+ /* Initialise the ring to empty. Clear errors. */
+ mutex_lock(&u->ring_cons_mutex);
+ spin_lock_irq(&port_user_lock);
+ u->ring_cons = u->ring_prod = u->ring_overflow = 0;
+ spin_unlock_irq(&port_user_lock);
+ mutex_unlock(&u->ring_cons_mutex);
+ rc = 0;
+ break;
+ }
+
+ default:
+ rc = -ENOSYS;
+ break;
+ }
+
+ return rc;
+}
+
+static unsigned int evtchn_poll(struct file *file, poll_table *wait)
+{
+ unsigned int mask = POLLOUT | POLLWRNORM;
+ struct per_user_data *u = file->private_data;
+
+ poll_wait(file, &u->evtchn_wait, wait);
+ if (u->ring_cons != u->ring_prod)
+ mask |= POLLIN | POLLRDNORM;
+ if (u->ring_overflow)
+ mask = POLLERR;
+ return mask;
+}
+
+static int evtchn_fasync(int fd, struct file *filp, int on)
+{
+ struct per_user_data *u = filp->private_data;
+ return fasync_helper(fd, filp, on, &u->evtchn_async_queue);
+}
+
+static int evtchn_open(struct inode *inode, struct file *filp)
+{
+ struct per_user_data *u;
+
+ if ((u = kmalloc(sizeof(*u), GFP_KERNEL)) == NULL)
+ return -ENOMEM;
+
+ memset(u, 0, sizeof(*u));
+ init_waitqueue_head(&u->evtchn_wait);
+
+ u->ring = (evtchn_port_t *)__get_free_page(GFP_KERNEL);
+ if (u->ring == NULL) {
+ kfree(u);
+ return -ENOMEM;
+ }
+
+ mutex_init(&u->ring_cons_mutex);
+
+ filp->private_data = u;
+
+ u->bind_cpu = -1;
+
+ return 0;
+}
+
+static int evtchn_release(struct inode *inode, struct file *filp)
+{
+ int i;
+ struct per_user_data *u = filp->private_data;
+ struct evtchn_close close;
+
+ spin_lock_irq(&port_user_lock);
+
+ free_page((unsigned long)u->ring);
+
+ for (i = 0; i < NR_EVENT_CHANNELS; i++) {
+ int ret;
+ if (port_user[i] != u)
+ continue;
+
+ port_user[i] = NULL;
+ mask_evtchn(i);
+
+ close.port = i;
+ ret = HYPERVISOR_event_channel_op(EVTCHNOP_close, &close);
+ BUG_ON(ret);
+ }
+
+ spin_unlock_irq(&port_user_lock);
+
+ kfree(u);
+
+ return 0;
+}
+
+static const struct file_operations evtchn_fops = {
+ .owner = THIS_MODULE,
+ .read = evtchn_read,
+ .write = evtchn_write,
+ .unlocked_ioctl = evtchn_ioctl,
+ .poll = evtchn_poll,
+ .fasync = evtchn_fasync,
+ .open = evtchn_open,
+ .release = evtchn_release,
+};
+
+static struct miscdevice evtchn_miscdev = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "evtchn",
+ .fops = &evtchn_fops,
+};
+
+static int __cpuinit evtchn_cpu_notify(struct notifier_block *nfb,
+ unsigned long action, void *hcpu)
+{
+ int hotcpu = (unsigned long)hcpu;
+ cpumask_t map = cpu_online_map;
+ int port, newcpu;
+ struct per_user_data *u;
+
+ switch (action) {
+ case CPU_DOWN_PREPARE:
+ cpu_clear(hotcpu, map);
+ spin_lock_irq(&port_user_lock);
+ for (port = 0; port < NR_EVENT_CHANNELS; port++) {
+ if ((u = port_user[port]) != NULL &&
+ u->bind_cpu == hotcpu &&
+ (newcpu = next_bind_cpu(map)) < NR_CPUS) {
+ rebind_irq_to_cpu(port, newcpu);
+ u->bind_cpu = newcpu;
+ }
+ }
+ spin_unlock_irq(&port_user_lock);
+ break;
+ default:
+ return NOTIFY_DONE;
+ }
+ return NOTIFY_OK;
+}
+
+static struct notifier_block __cpuinitdata evtchn_cpu_nfb = {
+ .notifier_call = evtchn_cpu_notify
+};
+
+int evtchn_init(void)
+{
+ int err;
+
+ spin_lock_init(&port_user_lock);
+ memset(port_user, 0, sizeof(port_user));
+
+ register_evtchn_upcall_notifier(&evtchn_upcall_nfb);
+ register_cpu_notifier(&evtchn_cpu_nfb);
+
+ err = misc_register(&evtchn_miscdev);
+ if (err != 0) {
+ printk(KERN_ALERT "Could not register /dev/xen/evtchn\n");
+ goto fail;
+ }
+
+ return 0;
+
+ fail:
+ unregister_cpu_notifier(&evtchn_cpu_nfb);
+ unregister_evtchn_upcall_notifier(&evtchn_upcall_nfb);
+ return err;
+}
+
+void evtchn_exit(void)
+{
+ misc_deregister(&evtchn_miscdev);
+ unregister_cpu_notifier(&evtchn_cpu_nfb);
+ unregister_evtchn_upcall_notifier(&evtchn_upcall_nfb);
+}
diff --git a/drivers/xen/xenctrl/main.c b/drivers/xen/xenctrl/main.c
index 95e1b3b..a2d5ca3 100644
--- a/drivers/xen/xenctrl/main.c
+++ b/drivers/xen/xenctrl/main.c
@@ -67,8 +67,13 @@ static int __init xenctrl_init(void)
if (ret)
goto fail4;
+ ret = evtchn_init();
+ if (ret)
+ goto fail5;
+
return 0;
+ fail5: xenbus_remove_proc_entry();
fail4: xsd_remove_proc_entry();
fail3: privcmd_remove_proc_entry();
fail2: capabilities_remove_proc_entry();
@@ -78,6 +83,7 @@ static int __init xenctrl_init(void)
static void __exit xenctrl_exit(void)
{
+ evtchn_exit();
xenbus_remove_proc_entry();
xsd_remove_proc_entry();
privcmd_remove_proc_entry();
diff --git a/drivers/xen/xenctrl/xenctrl.h b/drivers/xen/xenctrl/xenctrl.h
index 5990be5..63117bd 100644
--- a/drivers/xen/xenctrl/xenctrl.h
+++ b/drivers/xen/xenctrl/xenctrl.h
@@ -53,3 +53,9 @@ void xsd_remove_proc_entry(void);
*/
int xenbus_create_proc_entry(void);
void xenbus_remove_proc_entry(void);
+
+/*
+ * evtchn.c
+ */
+int evtchn_init(void);
+void evtchn_exit(void);
diff --git a/include/xen/events.h b/include/xen/events.h
index 0436486..7b3ee9e 100644
--- a/include/xen/events.h
+++ b/include/xen/events.h
@@ -2,6 +2,7 @@
#define _XEN_EVENTS_H
#include <linux/interrupt.h>
+#include <linux/notifier.h>
#include <xen/interface/event_channel.h>
#include <asm/xen/hypercall.h>
@@ -38,6 +39,12 @@ int bind_ipi_to_irqhandler(enum ipi_vector ipi,
*/
void unbind_from_irqhandler(unsigned int irq, void *dev_id);
+void mask_evtchn(int port);
+void unmask_evtchn(int port);
+void clear_evtchn(int port);
+
+void rebind_irq_to_cpu(unsigned irq, unsigned tcpu);
+
void xen_send_IPI_one(unsigned int cpu, enum ipi_vector vector);
static inline void notify_remote_via_evtchn(int port)
@@ -47,4 +54,8 @@ static inline void notify_remote_via_evtchn(int port)
}
extern void notify_remote_via_irq(int irq);
+
+int register_evtchn_upcall_notifier(struct notifier_block *n);
+int unregister_evtchn_upcall_notifier(struct notifier_block *n);
+
#endif /* _XEN_EVENTS_H */
diff --git a/include/xen/sys/evtchn.h b/include/xen/sys/evtchn.h
new file mode 100644
index 0000000..938d4da
--- /dev/null
+++ b/include/xen/sys/evtchn.h
@@ -0,0 +1,88 @@
+/******************************************************************************
+ * evtchn.h
+ *
+ * Interface to /dev/xen/evtchn.
+ *
+ * Copyright (c) 2003-2005, K A Fraser
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation; or, when distributed
+ * separately from the Linux kernel or incorporated into other
+ * software packages, subject to the following license:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this source file (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef __LINUX_PUBLIC_EVTCHN_H__
+#define __LINUX_PUBLIC_EVTCHN_H__
+
+/*
+ * Bind a fresh port to VIRQ @virq.
+ * Return allocated port.
+ */
+#define IOCTL_EVTCHN_BIND_VIRQ \
+ _IOC(_IOC_NONE, 'E', 0, sizeof(struct ioctl_evtchn_bind_virq))
+struct ioctl_evtchn_bind_virq {
+ unsigned int virq;
+};
+
+/*
+ * Bind a fresh port to remote <@remote_domain, @remote_port>.
+ * Return allocated port.
+ */
+#define IOCTL_EVTCHN_BIND_INTERDOMAIN \
+ _IOC(_IOC_NONE, 'E', 1, sizeof(struct ioctl_evtchn_bind_interdomain))
+struct ioctl_evtchn_bind_interdomain {
+ unsigned int remote_domain, remote_port;
+};
+
+/*
+ * Allocate a fresh port for binding to @remote_domain.
+ * Return allocated port.
+ */
+#define IOCTL_EVTCHN_BIND_UNBOUND_PORT \
+ _IOC(_IOC_NONE, 'E', 2, sizeof(struct ioctl_evtchn_bind_unbound_port))
+struct ioctl_evtchn_bind_unbound_port {
+ unsigned int remote_domain;
+};
+
+/*
+ * Unbind previously allocated @port.
+ */
+#define IOCTL_EVTCHN_UNBIND \
+ _IOC(_IOC_NONE, 'E', 3, sizeof(struct ioctl_evtchn_unbind))
+struct ioctl_evtchn_unbind {
+ unsigned int port;
+};
+
+/*
+ * Unbind previously allocated @port.
+ */
+#define IOCTL_EVTCHN_NOTIFY \
+ _IOC(_IOC_NONE, 'E', 4, sizeof(struct ioctl_evtchn_notify))
+struct ioctl_evtchn_notify {
+ unsigned int port;
+};
+
+/* Clear and reinitialise the event buffer. Clear error condition. */
+#define IOCTL_EVTCHN_RESET \
+ _IOC(_IOC_NONE, 'E', 5, 0)
+
+#endif /* __LINUX_PUBLIC_EVTCHN_H__ */
--
1.5.4.1
linux-2.6-0055-xen-Add-__init-__exit-notations-to-xenctrl-function.patch:
--- NEW FILE linux-2.6-0055-xen-Add-__init-__exit-notations-to-xenctrl-function.patch ---
>From ad1aeb74ebf2d336685a7d2f0ffb623ca174ebc5 Mon Sep 17 00:00:00 2001
From: Mark McLoughlin <markmc redhat com>
Date: Thu, 7 Feb 2008 15:37:30 +0000
Subject: [PATCH] xen: Add __init/__exit notations to xenctrl function
Signed-off-by: Mark McLoughlin <markmc redhat com>
---
drivers/xen/xenctrl/capabilities.c | 4 ++--
drivers/xen/xenctrl/evtchn.c | 4 ++--
drivers/xen/xenctrl/privcmd.c | 4 ++--
drivers/xen/xenctrl/xenbus.c | 4 ++--
drivers/xen/xenctrl/xenctrl.h | 22 ++++++++++++----------
drivers/xen/xenctrl/xenstore.c | 4 ++--
6 files changed, 22 insertions(+), 20 deletions(-)
diff --git a/drivers/xen/xenctrl/capabilities.c b/drivers/xen/xenctrl/capabilities.c
index 66443fb..1ff078a 100644
--- a/drivers/xen/xenctrl/capabilities.c
+++ b/drivers/xen/xenctrl/capabilities.c
@@ -48,7 +48,7 @@ static int capabilities_read(char *page, char **start, off_t off,
return len;
}
-int capabilities_create_proc_entry(void)
+int __init capabilities_create_proc_entry(void)
{
struct proc_dir_entry *entry;
@@ -62,7 +62,7 @@ int capabilities_create_proc_entry(void)
return 0;
}
-void capabilities_remove_proc_entry(void)
+void __exit capabilities_remove_proc_entry(void)
{
remove_proc_entry("xen/capabilities", NULL);
}
diff --git a/drivers/xen/xenctrl/evtchn.c b/drivers/xen/xenctrl/evtchn.c
index 22fabe2..d894632 100644
--- a/drivers/xen/xenctrl/evtchn.c
+++ b/drivers/xen/xenctrl/evtchn.c
@@ -520,7 +520,7 @@ static struct notifier_block __cpuinitdata evtchn_cpu_nfb = {
.notifier_call = evtchn_cpu_notify
};
-int evtchn_init(void)
+int __init evtchn_init(void)
{
int err;
@@ -544,7 +544,7 @@ int evtchn_init(void)
return err;
}
-void evtchn_exit(void)
+void __exit evtchn_exit(void)
{
misc_deregister(&evtchn_miscdev);
unregister_cpu_notifier(&evtchn_cpu_nfb);
diff --git a/drivers/xen/xenctrl/privcmd.c b/drivers/xen/xenctrl/privcmd.c
index 1746a17..cf74948 100644
--- a/drivers/xen/xenctrl/privcmd.c
+++ b/drivers/xen/xenctrl/privcmd.c
@@ -68,7 +68,7 @@ static const struct file_operations privcmd_file_ops = {
.unlocked_ioctl = privcmd_ioctl,
};
-int privcmd_create_proc_entry(void)
+int __init privcmd_create_proc_entry(void)
{
static struct proc_dir_entry *entry;
@@ -82,7 +82,7 @@ int privcmd_create_proc_entry(void)
return 0;
}
-void privcmd_remove_proc_entry(void)
+void __exit privcmd_remove_proc_entry(void)
{
remove_proc_entry("xen/privcmd", NULL);
}
diff --git a/drivers/xen/xenctrl/xenbus.c b/drivers/xen/xenctrl/xenbus.c
index 8127dc8..57d5501 100644
--- a/drivers/xen/xenctrl/xenbus.c
+++ b/drivers/xen/xenctrl/xenbus.c
@@ -378,7 +378,7 @@ static const struct file_operations xenbus_dev_file_ops = {
.poll = xenbus_dev_poll,
};
-int xenbus_create_proc_entry(void)
+int __init xenbus_create_proc_entry(void)
{
struct proc_dir_entry *entry;
@@ -392,7 +392,7 @@ int xenbus_create_proc_entry(void)
return 0;
}
-void xenbus_remove_proc_entry(void)
+void __exit xenbus_remove_proc_entry(void)
{
remove_proc_entry("xen/xenbus", NULL);
}
diff --git a/drivers/xen/xenctrl/xenctrl.h b/drivers/xen/xenctrl/xenctrl.h
index 63117bd..9ca6b1f 100644
--- a/drivers/xen/xenctrl/xenctrl.h
+++ b/drivers/xen/xenctrl/xenctrl.h
@@ -30,32 +30,34 @@
* IN THE SOFTWARE.
*/
+#include <linux/init.h>
+
/*
* capabilities.c
*/
-int capabilities_create_proc_entry(void);
-void capabilities_remove_proc_entry(void);
+int capabilities_create_proc_entry(void) __init;
+void capabilities_remove_proc_entry(void) __exit;
/*
* privcmd.c
*/
-int privcmd_create_proc_entry(void);
-void privcmd_remove_proc_entry(void);
+int privcmd_create_proc_entry(void) __init;
+void privcmd_remove_proc_entry(void) __exit;
/*
* xenstore.c
*/
-int xsd_create_proc_entry(void);
-void xsd_remove_proc_entry(void);
+int xsd_create_proc_entry(void) __init;
+void xsd_remove_proc_entry(void) __exit;
/*
* xenbus.c
*/
-int xenbus_create_proc_entry(void);
-void xenbus_remove_proc_entry(void);
+int xenbus_create_proc_entry(void) __init;
+void xenbus_remove_proc_entry(void) __exit;
/*
* evtchn.c
*/
-int evtchn_init(void);
-void evtchn_exit(void);
+int evtchn_init(void) __init;
+void evtchn_exit(void) __exit;
diff --git a/drivers/xen/xenctrl/xenstore.c b/drivers/xen/xenctrl/xenstore.c
index 4b38ff5..9b16e82 100644
--- a/drivers/xen/xenctrl/xenstore.c
+++ b/drivers/xen/xenctrl/xenstore.c
@@ -84,7 +84,7 @@ static int xsd_port_read(char *page, char **start, off_t off,
return len;
}
-int xsd_create_proc_entry(void)
+int __init xsd_create_proc_entry(void)
{
struct proc_dir_entry *entry;
@@ -111,7 +111,7 @@ int xsd_create_proc_entry(void)
return - ENOMEM;
}
-void xsd_remove_proc_entry(void)
+void __exit xsd_remove_proc_entry(void)
{
remove_proc_entry("xen/xsd_port", NULL);
remove_proc_entry("xen/xsd_kva", NULL);
--
1.5.4.1
linux-2.6-0056-xen-Add-Xen-s-sys-hypervisor-interface.patch:
--- NEW FILE linux-2.6-0056-xen-Add-Xen-s-sys-hypervisor-interface.patch ---
>From 4cb49c6a7650381ba772fe3ee401d55cf934601c Mon Sep 17 00:00:00 2001
From: Mark McLoughlin <markmc redhat com>
Date: Thu, 7 Feb 2008 15:32:28 +0000
Subject: [PATCH] xen: Add Xen's /sys/hypervisor interface
Hook up Xen's /sys/hypervisor interface:
/sys/hypervisor/
-> type
-> uuid
-> compilation
-> compile_date
-> compiled_by
-> compiler
-> properties
-> capabilities
-> changeset
-> pagesize
-> virtual_start
-> writable_pt
-> version
-> extra
-> major
-> minor
Note: the hypervisor subsys hook requires that
SYS_HYPERVISOR is selected to enabled it, which in
turns means that the subsys will be registered by
a pv-ops kernel with Xen support, even on bare
metal. This hook needs to be changed to be runtime
enabled.
Signed-off-by: Mark McLoughlin <markmc redhat com>
---
arch/x86/xen/Kconfig | 3 +-
drivers/xen/xenctrl/Makefile | 1 +
drivers/xen/xenctrl/main.c | 6 +
drivers/xen/xenctrl/sysfs.c | 349 +++++++++++++++++++++++++++++++++++++++
drivers/xen/xenctrl/xenctrl.h | 6 +
include/xen/interface/version.h | 6 +
6 files changed, 370 insertions(+), 1 deletions(-)
create mode 100644 drivers/xen/xenctrl/sysfs.c
diff --git a/arch/x86/xen/Kconfig b/arch/x86/xen/Kconfig
index 7f01d14..f2974af 100644
--- a/arch/x86/xen/Kconfig
+++ b/arch/x86/xen/Kconfig
@@ -13,8 +13,9 @@ config XEN
config XENCTRL
tristate "Xen's user space control interfaces"
- depends on XEN && PROC_FS
+ depends on XEN && PROC_FS && SYSFS
default m if XEN
+ select SYS_HYPERVISOR
help
This is the /proc/xen and /dev/evtchn interfaces used by
Xen's libxc and xenstored.
diff --git a/drivers/xen/xenctrl/Makefile b/drivers/xen/xenctrl/Makefile
index efc12c2..b14836e 100644
--- a/drivers/xen/xenctrl/Makefile
+++ b/drivers/xen/xenctrl/Makefile
@@ -7,3 +7,4 @@ xenctrl-objs += privcmd.o
xenctrl-objs += xenstore.o
xenctrl-objs += xenbus.o
xenctrl-objs += evtchn.o
+xenctrl-objs += sysfs.o
diff --git a/drivers/xen/xenctrl/main.c b/drivers/xen/xenctrl/main.c
index a2d5ca3..f6c715d 100644
--- a/drivers/xen/xenctrl/main.c
+++ b/drivers/xen/xenctrl/main.c
@@ -71,8 +71,13 @@ static int __init xenctrl_init(void)
if (ret)
goto fail5;
+ ret = sys_hypervisor_init();
+ if (ret)
+ goto fail6;
+
return 0;
+ fail6: sys_hypervisor_exit();
fail5: xenbus_remove_proc_entry();
fail4: xsd_remove_proc_entry();
fail3: privcmd_remove_proc_entry();
@@ -83,6 +88,7 @@ static int __init xenctrl_init(void)
static void __exit xenctrl_exit(void)
{
+ sys_hypervisor_exit();
evtchn_exit();
xenbus_remove_proc_entry();
xsd_remove_proc_entry();
diff --git a/drivers/xen/xenctrl/sysfs.c b/drivers/xen/xenctrl/sysfs.c
new file mode 100644
index 0000000..3b38aaf
--- /dev/null
+++ b/drivers/xen/xenctrl/sysfs.c
@@ -0,0 +1,349 @@
+/*
+ * copyright (c) 2006 IBM Corporation
+ * Authored by: Mike D. Day <ncmike us ibm com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kobject.h>
+#include <linux/sysfs.h>
+#include <linux/err.h>
+#include <asm/xen/hypervisor.h>
+#include <xen/xenbus.h>
+#include "xenctrl.h"
+
+#define HYPERVISOR_ATTR_RO(_name) \
+static struct subsys_attribute _name##_attr = __ATTR_RO(_name)
+
+#define HYPERVISOR_ATTR_RW(_name) \
+static struct subsys_attribute _name##_attr = \
+ __ATTR(_name, 0644, _name##_show, _name##_store)
+
+static ssize_t type_show(struct kset *kset, char *buffer)
+{
+ return sprintf(buffer, "xen\n");
+}
+
+HYPERVISOR_ATTR_RO(type);
+
+static int __init xen_sysfs_type_init(void)
+{
+ return sysfs_create_file(&hypervisor_subsys.kobj, &type_attr.attr);
+}
+
+static void xen_sysfs_type_destroy(void)
+{
+ sysfs_remove_file(&hypervisor_subsys.kobj, &type_attr.attr);
+}
+
+static ssize_t major_show(struct kset *kset, char *buffer)
+{
+ int version;
+
+ version = HYPERVISOR_xen_version(XENVER_version, NULL);
+ if (!version)
+ return -ENODEV;
+
+ return sprintf(buffer, "%d\n", version >> 16);
+}
+
+HYPERVISOR_ATTR_RO(major);
+
+static ssize_t minor_show(struct kset *kset, char *buffer)
+{
+ int version;
+
+ version = HYPERVISOR_xen_version(XENVER_version, NULL);
+ if (!version)
+ return -ENODEV;
+
+ return sprintf(buffer, "%d\n", version & 0xff);
+}
+
+HYPERVISOR_ATTR_RO(minor);
+
+static ssize_t extra_show(struct kset *kset, char *buffer)
+{
+ int ret;
+ struct xen_extraversion extra;
+
+ ret = HYPERVISOR_xen_version(XENVER_extraversion, &extra);
+ if (ret)
+ return ret;
+
+ return sprintf(buffer, "%s\n", extra.extraversion);
+}
+
+HYPERVISOR_ATTR_RO(extra);
+
+static struct attribute *version_attrs[] = {
+ &major_attr.attr,
+ &minor_attr.attr,
+ &extra_attr.attr,
+ NULL
+};
+
+static struct attribute_group version_group = {
+ .name = "version",
+ .attrs = version_attrs,
+};
+
+static int __init xen_sysfs_version_init(void)
+{
+ return sysfs_create_group(&hypervisor_subsys.kobj, &version_group);
+}
+
+static void xen_sysfs_version_destroy(void)
+{
+ sysfs_remove_group(&hypervisor_subsys.kobj, &version_group);
+}
+
+static ssize_t uuid_show(struct kset *kset, char *buffer)
+{
+ char *vm, *val;
+ int ret;
+
+ vm = xenbus_read(XBT_NIL, "vm", "", NULL);
+ if (IS_ERR(vm))
+ return PTR_ERR(vm);
+
+ val = xenbus_read(XBT_NIL, vm, "uuid", NULL);
+ if (IS_ERR(val)) {
+ ret = PTR_ERR(val);
+ goto out;
+ }
+
+ ret = sprintf(buffer, "%s\n", val);
+
+ kfree(val);
+out: kfree(vm);
+
+ return ret;
+}
+
+HYPERVISOR_ATTR_RO(uuid);
+
+static int __init xen_sysfs_uuid_init(void)
+{
+ return sysfs_create_file(&hypervisor_subsys.kobj, &uuid_attr.attr);
+}
+
+static void xen_sysfs_uuid_destroy(void)
+{
+ sysfs_remove_file(&hypervisor_subsys.kobj, &uuid_attr.attr);
+}
+
+static ssize_t compiler_show(struct kset *kset, char *buffer)
+{
+ struct xen_compile_info info;
+ int ret;
+
+ ret = HYPERVISOR_xen_version(XENVER_compile_info, &info);
+ if (ret)
+ return ret;
+
+ return sprintf(buffer, "%s\n", info.compiler);
+}
+
+HYPERVISOR_ATTR_RO(compiler);
+
+static ssize_t compiled_by_show(struct kset *kset, char *buffer)
+{
+ struct xen_compile_info info;
+ int ret;
+
+ ret = HYPERVISOR_xen_version(XENVER_compile_info, &info);
+ if (ret)
+ return ret;
+
+ return sprintf(buffer, "%s\n", info.compile_by);
+}
+
+HYPERVISOR_ATTR_RO(compiled_by);
+
+static ssize_t compile_date_show(struct kset *kset, char *buffer)
+{
+ struct xen_compile_info info;
+ int ret;
+
+ ret = HYPERVISOR_xen_version(XENVER_compile_info, &info);
+ if (ret)
+ return ret;
+
+ return sprintf(buffer, "%s\n", info.compile_date);
+}
+
+HYPERVISOR_ATTR_RO(compile_date);
+
+static struct attribute *xen_compile_attrs[] = {
+ &compiler_attr.attr,
+ &compiled_by_attr.attr,
+ &compile_date_attr.attr,
+ NULL
+};
+
+static struct attribute_group xen_compilation_group = {
+ .name = "compilation",
+ .attrs = xen_compile_attrs,
+};
+
+static int __init xen_compilation_init(void)
+{
+ return sysfs_create_group(&hypervisor_subsys.kobj,
+ &xen_compilation_group);
+}
+
+static void xen_compilation_destroy(void)
+{
+ sysfs_remove_group(&hypervisor_subsys.kobj,
+ &xen_compilation_group);
+}
+
+static ssize_t capabilities_show(struct kset *kset, char *buffer)
+{
+ struct xen_capabilities_info *caps;
+ int ret;
+
+ caps = kmalloc(sizeof(struct xen_capabilities_info), GFP_KERNEL);
+ if (!caps)
+ return -ENOMEM;
+
+ ret = HYPERVISOR_xen_version(XENVER_capabilities, caps);
+ if (ret)
+ goto out;
+
+ ret = sprintf(buffer, "%s\n", caps->info);
+
+out: kfree(caps);
+
+ return ret;
+}
+
+HYPERVISOR_ATTR_RO(capabilities);
+
+static ssize_t changeset_show(struct kset *kset, char *buffer)
+{
+ struct xen_changeset_info cset;
+ int ret;
+
+ ret = HYPERVISOR_xen_version(XENVER_changeset, &cset);
+ if (ret)
+ return ret;
+
+ return sprintf(buffer, "%s\n", cset.info);
+}
+
+HYPERVISOR_ATTR_RO(changeset);
+
+static ssize_t virtual_start_show(struct kset *kset, char *buffer)
+{
+ struct xen_platform_parameters parms;
+ int ret;
+
+ ret = HYPERVISOR_xen_version(XENVER_platform_parameters, &parms);
+ if (ret)
+ return ret;
+
+ return sprintf(buffer, "%lx\n", parms.virt_start);
+}
+
+HYPERVISOR_ATTR_RO(virtual_start);
+
+static ssize_t pagesize_show(struct kset *kset, char *buffer)
+{
+ int ret;
+
+ ret = HYPERVISOR_xen_version(XENVER_pagesize, NULL);
+ if (ret < 0)
+ return ret;
+
+ return sprintf(buffer, "%x\n", ret);
+}
+
+HYPERVISOR_ATTR_RO(pagesize);
+
+static ssize_t writable_pt_show(struct kset *kset, char *buffer)
+{
+ struct xen_feature_info info;
+ int ret;
+
+ info.submap_idx = XENFEAT_writable_page_tables;
+
+ ret = HYPERVISOR_xen_version(XENVER_get_features, &info);
+ if (ret)
+ return ret;
+
+ return sprintf(buffer, "%d\n", info.submap);
+}
+
+HYPERVISOR_ATTR_RO(writable_pt);
+
+static struct attribute *xen_properties_attrs[] = {
+ &capabilities_attr.attr,
+ &changeset_attr.attr,
+ &virtual_start_attr.attr,
+ &pagesize_attr.attr,
+ &writable_pt_attr.attr,
+ NULL
+};
+
+static struct attribute_group xen_properties_group = {
+ .name = "properties",
+ .attrs = xen_properties_attrs,
+};
+
+static int __init xen_properties_init(void)
+{
+ return sysfs_create_group(&hypervisor_subsys.kobj,
+ &xen_properties_group);
+}
+
+static void xen_properties_destroy(void)
+{
+ sysfs_remove_group(&hypervisor_subsys.kobj, &xen_properties_group);
+}
+
+int __init sys_hypervisor_init(void)
+{
+ int ret;
+
+ if (!is_running_on_xen())
+ return -ENODEV;
+
+ ret = xen_sysfs_type_init();
+ if (ret)
+ goto out;
+ ret = xen_sysfs_version_init();
+ if (ret)
+ goto version_out;
+ ret = xen_compilation_init();
+ if (ret)
+ goto comp_out;
+ ret = xen_sysfs_uuid_init();
+ if (ret)
+ goto uuid_out;
+ ret = xen_properties_init();
+ if (!ret)
+ goto out;
+
+ xen_sysfs_uuid_destroy();
+uuid_out:
+ xen_compilation_destroy();
+comp_out:
+ xen_sysfs_version_destroy();
+version_out:
+ xen_sysfs_type_destroy();
+out:
+ return ret;
+}
+
+void __exit sys_hypervisor_exit(void)
+{
+ xen_properties_destroy();
+ xen_compilation_destroy();
+ xen_sysfs_uuid_destroy();
+ xen_sysfs_version_destroy();
+ xen_sysfs_type_destroy();
+}
diff --git a/drivers/xen/xenctrl/xenctrl.h b/drivers/xen/xenctrl/xenctrl.h
index 9ca6b1f..5c6d899 100644
--- a/drivers/xen/xenctrl/xenctrl.h
+++ b/drivers/xen/xenctrl/xenctrl.h
@@ -61,3 +61,9 @@ void xenbus_remove_proc_entry(void) __exit;
*/
int evtchn_init(void) __init;
void evtchn_exit(void) __exit;
+
+/*
+ * sysfs.c
+ */
+int sys_hypervisor_init(void) __init;
+void sys_hypervisor_exit(void) __exit;
diff --git a/include/xen/interface/version.h b/include/xen/interface/version.h
index 453235e..dd58cf5 100644
--- a/include/xen/interface/version.h
+++ b/include/xen/interface/version.h
@@ -57,4 +57,10 @@ struct xen_feature_info {
/* Declares the features reported by XENVER_get_features. */
#include "features.h"
+/* arg == NULL; returns host memory page size. */
+#define XENVER_pagesize 7
+
+/* arg == xen_domain_handle_t. */
+#define XENVER_guest_handle 8
+
#endif /* __XEN_PUBLIC_VERSION_H__ */
--
1.5.4.1
linux-2.6-0057-xen-dom0-Add-basic-proc-xen-balloon.patch:
--- NEW FILE linux-2.6-0057-xen-dom0-Add-basic-proc-xen-balloon.patch ---
>From a5c0567769e088973ab955040d407834f51bcb2a Mon Sep 17 00:00:00 2001
From: Mark McLoughlin <markmc redhat com>
Date: Thu, 7 Feb 2008 19:11:54 +0000
Subject: [PATCH] xen dom0: Add basic /proc/xen/balloon
Userspace querys Dom0's current memory allocation using
/proc/xen/balloon. This implements that basic functionality,
leaving out the rest of the fields usually reported by
this interface.
Signed-off-by: Mark McLoughlin <markmc redhat com>
---
drivers/xen/xenctrl/Makefile | 1 +
drivers/xen/xenctrl/balloon.c | 68 +++++++++++++++++++++++++++++++++++++++++
drivers/xen/xenctrl/main.c | 12 +++++--
drivers/xen/xenctrl/xenctrl.h | 6 +++
4 files changed, 84 insertions(+), 3 deletions(-)
create mode 100644 drivers/xen/xenctrl/balloon.c
diff --git a/drivers/xen/xenctrl/Makefile b/drivers/xen/xenctrl/Makefile
index b14836e..823bb16 100644
--- a/drivers/xen/xenctrl/Makefile
+++ b/drivers/xen/xenctrl/Makefile
@@ -6,5 +6,6 @@ xenctrl-objs += capabilities.o
xenctrl-objs += privcmd.o
xenctrl-objs += xenstore.o
xenctrl-objs += xenbus.o
+xenctrl-objs += balloon.o
xenctrl-objs += evtchn.o
xenctrl-objs += sysfs.o
diff --git a/drivers/xen/xenctrl/balloon.c b/drivers/xen/xenctrl/balloon.c
new file mode 100644
index 0000000..c8c1c13
--- /dev/null
+++ b/drivers/xen/xenctrl/balloon.c
@@ -0,0 +1,68 @@
+/******************************************************************************
+ *
+ * balloon.c
+ *
+ * /proc/xen/balloon
+ *
+ * Copyright (c) 2003, B Dragovic
+ * Copyright (c) 2003-2004, M Williamson, K Fraser
+ * Copyright (c) 2005 Dan M. Smith, IBM Corporation
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation; or, when distributed
+ * separately from the Linux kernel or incorporated into other
+ * software packages, subject to the following license:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this source file (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <linux/proc_fs.h>
+#include <linux/module.h>
+#include <linux/bootmem.h>
+#include <asm/xen/hypervisor.h>
+
+#define PAGES2KB(_p) ((_p)<<(PAGE_SHIFT-10))
+
+static int balloon_read(char *page, char **start, off_t off,
+ int count, int *eof, void *data)
+{
+ *eof = 1;
+ return sprintf(page, "Current allocation: %8lu kB\n",
+ PAGES2KB(xen_start_info->nr_pages));
+}
+
+int __init balloon_create_proc_entry(void)
+{
+ struct proc_dir_entry *entry;
+
+ entry = create_proc_entry("xen/balloon", 0644, NULL);
+ if (!entry)
+ return -ENOMEM;
+
+ entry->owner = THIS_MODULE;
+ entry->read_proc = balloon_read;
+
+ return 0;
+}
+
+void __exit balloon_remove_proc_entry(void)
+{
+ remove_proc_entry("xen/balloon", NULL);
+}
diff --git a/drivers/xen/xenctrl/main.c b/drivers/xen/xenctrl/main.c
index f6c715d..fe3e793 100644
--- a/drivers/xen/xenctrl/main.c
+++ b/drivers/xen/xenctrl/main.c
@@ -67,17 +67,22 @@ static int __init xenctrl_init(void)
if (ret)
goto fail4;
- ret = evtchn_init();
+ ret = balloon_create_proc_entry();
if (ret)
goto fail5;
- ret = sys_hypervisor_init();
+ ret = evtchn_init();
if (ret)
goto fail6;
+ ret = sys_hypervisor_init();
+ if (ret)
+ goto fail7;
+
return 0;
- fail6: sys_hypervisor_exit();
+ fail7: sys_hypervisor_exit();
+ fail6: balloon_remove_proc_entry();
fail5: xenbus_remove_proc_entry();
fail4: xsd_remove_proc_entry();
fail3: privcmd_remove_proc_entry();
@@ -90,6 +95,7 @@ static void __exit xenctrl_exit(void)
{
sys_hypervisor_exit();
evtchn_exit();
+ balloon_remove_proc_entry();
xenbus_remove_proc_entry();
xsd_remove_proc_entry();
privcmd_remove_proc_entry();
diff --git a/drivers/xen/xenctrl/xenctrl.h b/drivers/xen/xenctrl/xenctrl.h
index 5c6d899..105343f 100644
--- a/drivers/xen/xenctrl/xenctrl.h
+++ b/drivers/xen/xenctrl/xenctrl.h
@@ -57,6 +57,12 @@ int xenbus_create_proc_entry(void) __init;
void xenbus_remove_proc_entry(void) __exit;
/*
+ * balloon.c
+ */
+int balloon_create_proc_entry(void) __init;
+void balloon_remove_proc_entry(void) __exit;
+
+/*
* evtchn.c
*/
int evtchn_init(void) __init;
--
1.5.4.1
linux-2.6-0058-xen-dom0-Re-work-privcmd_ioctl-a-little.patch:
--- NEW FILE linux-2.6-0058-xen-dom0-Re-work-privcmd_ioctl-a-little.patch ---
>From 9ee1b3b4d416e0ab0b312df334460c84de42be9a Mon Sep 17 00:00:00 2001
From: Mark McLoughlin <markmc redhat com>
Date: Mon, 11 Feb 2008 11:23:54 +0000
Subject: [PATCH] xen dom0: Re-work privcmd_ioctl() a little
Re-organise the code in privcmd_ioctl() a little in
preparation for adding support for IOCTL_PRIVCMD_MMAP.
Signed-off-by: Mark McLoughlin <markmc redhat com>
---
drivers/xen/xenctrl/privcmd.c | 15 ++++-----------
1 files changed, 4 insertions(+), 11 deletions(-)
diff --git a/drivers/xen/xenctrl/privcmd.c b/drivers/xen/xenctrl/privcmd.c
index cf74948..58c4b83 100644
--- a/drivers/xen/xenctrl/privcmd.c
+++ b/drivers/xen/xenctrl/privcmd.c
@@ -39,29 +39,22 @@
static long privcmd_ioctl(struct file *file, unsigned int cmd,
unsigned long arg)
{
- int ret = -ENOSYS;
-
switch (cmd) {
case IOCTL_PRIVCMD_HYPERCALL: {
- privcmd_hypercall_t hypercall;
+ privcmd_hypercall_t cmd;
- if (copy_from_user(&hypercall, (void __user *)arg,
- sizeof(hypercall)))
+ if (copy_from_user(&cmd, (void __user *)arg, sizeof(cmd)))
return -EFAULT;
- ret = privcmd_hypercall(&hypercall);
- break;
+ return privcmd_hypercall(&cmd);
}
case IOCTL_PRIVCMD_MMAP:
case IOCTL_PRIVCMD_MMAPBATCH:
printk(KERN_WARNING "IOCTL_PRIVCMD_MMAP ioctl not yet implemented\n");
default:
- ret = -EINVAL;
- break;
+ return -EINVAL;
}
-
- return ret;
}
static const struct file_operations privcmd_file_ops = {
--
1.5.4.1
linux-2.6-0059-xen-dom0-Add-IOCTL_PRIVCMD_MMAP.patch:
--- NEW FILE linux-2.6-0059-xen-dom0-Add-IOCTL_PRIVCMD_MMAP.patch ---
>From c647aacea518e0a0b0358a04576a33aca697683b Mon Sep 17 00:00:00 2001
From: Mark McLoughlin <markmc redhat com>
Date: Thu, 7 Feb 2008 19:05:10 +0000
Subject: [PATCH] xen dom0: Add IOCTL_PRIVCMD_MMAP
IOCTL_PRIVCMD_MMAP is used by Dom0 userspace (via
libxc's xc_map_foreign_range() function) to map
pages from a foreign domain without requiring a
grant and without adding the page to Dom0's
p2m map.
Signed-off-by: Mark McLoughlin <markmc redhat com>
---
arch/x86/xen/ioremap.c | 30 +++++++
drivers/xen/xenctrl/privcmd.c | 176 +++++++++++++++++++++++++++++++++++++-
include/asm-x86/xen/hypervisor.h | 4 +
3 files changed, 207 insertions(+), 3 deletions(-)
diff --git a/arch/x86/xen/ioremap.c b/arch/x86/xen/ioremap.c
index 70f77bd..e963ff9 100644
--- a/arch/x86/xen/ioremap.c
+++ b/arch/x86/xen/ioremap.c
@@ -145,3 +145,33 @@ int xen_ioremap_page_range(unsigned long addr, unsigned long end,
return rc;
}
+int xen_map_foreign_range(struct vm_area_struct *vma, unsigned long addr,
+ unsigned long mfn, unsigned long size,
+ pgprot_t prot, domid_t domid)
+{
+ if (xen_feature(XENFEAT_auto_translated_physmap))
+ return remap_pfn_range(vma, addr, mfn, size, prot);
+
+ if (domid == DOMID_SELF)
+ return -EINVAL;
+
+ vma->vm_flags |= VM_IO | VM_RESERVED;
+
+#if 0
+ /* FIXME:
+ * has_foreign_mappings is needed to avoid a race
+ * condition whereby pages are freed by the unpin
+ * in arch_exit_mmap() and then allocated to the
+ * domain before the PTE is destroyed, leading to
+ * an erroneous reference count update. See:
+ *
+ * http://lists.xensource.com/archives/html/xen-devel/2006-08/msg00014.html
+ * http://xenbits.xensource.com/xen-unstable.hg?rev/e351aace191e
+ */
+ vma->vm_mm->context.has_foreign_mappings = 1;
+#endif
+
+ return __direct_remap_pfn_range(vma->vm_mm, addr, mfn,
+ size, prot, domid);
+}
+EXPORT_SYMBOL(xen_map_foreign_range);
diff --git a/drivers/xen/xenctrl/privcmd.c b/drivers/xen/xenctrl/privcmd.c
index 58c4b83..5622e87 100644
--- a/drivers/xen/xenctrl/privcmd.c
+++ b/drivers/xen/xenctrl/privcmd.c
@@ -33,8 +33,156 @@
#include <linux/proc_fs.h>
#include <linux/module.h>
#include <linux/uaccess.h>
+#include <linux/mm.h>
#include <asm/xen/hypervisor.h>
#include <xen/sys/privcmd.h>
+#include <xen/features.h>
+
+static struct page *privcmd_nopage(struct vm_area_struct *vma,
+ unsigned long address, int *type)
+{
+ return NOPAGE_SIGBUS;
+}
+
+static struct vm_operations_struct privcmd_vm_ops = {
+ .nopage = privcmd_nopage
+};
+
+static int privcmd_mmap(struct file *file, struct vm_area_struct *vma)
+{
+ /* Unsupported for auto-translate guests. */
+ if (xen_feature(XENFEAT_auto_translated_physmap))
+ return -ENOSYS;
+
+ /* FIXME:
+ * the VM_PFNMAP here may be dubious. See:
+ *
+ * http://lists.xensource.com/archives/html/xen-devel/2007-12/msg00207.html
+ *
+ * Note, in recent kernels it is also needed to
+ * avoid the mapping being dropped to VM_PRIVATE
+ * by vma_wants_writenotify()
+ */
+
+ /* DONTCOPY is essential for Xen as copy_page_range is broken. */
+ vma->vm_flags |= VM_RESERVED | VM_IO | VM_DONTCOPY | VM_PFNMAP;
+ vma->vm_ops = &privcmd_vm_ops;
+ vma->vm_private_data = NULL;
+
+ return 0;
+}
+
+static struct vm_area_struct *
+privcmd_verify_mapping(struct mm_struct *mm, unsigned long addr)
+{
+ struct vm_area_struct *vma;
+
+ vma = find_vma(mm, addr);
+ if (!vma || vma->vm_start != addr)
+ return NULL;
+
+ /* Disallow multiple mappings */
+ return xchg(&vma->vm_private_data, (void *)1) ? NULL : vma;
+}
+
+static int privcmd_mmap_cmd(privcmd_mmap_t *cmd)
+{
+ struct mm_struct *mm = current->mm;
+ struct vm_area_struct *vma;
+ privcmd_mmap_entry_t __user *p;
+ unsigned long va;
+ int i, ret = 0;
+
+ down_write(&mm->mmap_sem);
+
+ for (i = 0, p = cmd->entry, vma = NULL; i < cmd->num; i++, p++) {
+ privcmd_mmap_entry_t entry;
+ unsigned long end;
+
+ if (copy_from_user(&entry, p, sizeof(entry))) {
+ ret = -EFAULT;
+ break;
+ }
+
+ ret = -EINVAL;
+
+ if (!vma) {
+ vma = privcmd_verify_mapping(mm, entry.va);
+ if (!vma)
+ break;
+ va = vma->vm_start;
+ }
+
+ /* Do not allow range to wrap the address space. */
+ if (entry.npages > (LONG_MAX >> PAGE_SHIFT) ||
+ (unsigned long)(entry.npages << PAGE_SHIFT) >= -va)
+ break;
+
+ end = entry.va + (entry.npages << PAGE_SHIFT);
+
+ /* Range chunks must be contiguous in va space. */
+ if (entry.va != va || end > vma->vm_end)
+ break;
+
+ ret = xen_map_foreign_range(vma,
+ entry.va & PAGE_MASK,
+ entry.mfn,
+ entry.npages << PAGE_SHIFT,
+ vma->vm_page_prot,
+ cmd->dom);
+ if (ret < 0)
+ break;
+
+ va = end;
+ }
+
+ up_write(&mm->mmap_sem);
+
+ return ret;
+}
+
+static int privcmd_mmap_batch_cmd(privcmd_mmapbatch_t *cmd)
+{
+ struct mm_struct *mm = current->mm;
+ struct vm_area_struct *vma;
+ int i;
+
+ if (cmd->num <= 0 || cmd->num > (LONG_MAX >> PAGE_SHIFT))
+ return -EINVAL;
+
+ down_write(&mm->mmap_sem);
+
+ vma = privcmd_verify_mapping(mm, cmd->addr);
+ if (!vma ||
+ cmd->addr + (cmd->num << PAGE_SHIFT) != vma->vm_end) {
+ up_write(&mm->mmap_sem);
+ return -EINVAL;
+ }
+
+ for (i = 0; i < cmd->num; i++) {
+ unsigned long __user *p;
+ unsigned long addr, mfn;
+ int ret;
+
+ p = cmd->arr + i;
+
+ if (get_user(mfn, p)) {
+ up_write(&mm->mmap_sem);
+ return -EFAULT;
+ }
+
+ addr = (cmd->addr & PAGE_MASK) + (i << PAGE_SHIFT);
+
+ ret = xen_map_foreign_range(vma, addr, mfn, PAGE_SIZE,
+ vma->vm_page_prot, cmd->dom);
+ if (ret < 0)
+ put_user(0xF0000000 | mfn, p);
+ }
+
+ up_write(&mm->mmap_sem);
+
+ return 0;
+}
static long privcmd_ioctl(struct file *file, unsigned int cmd,
unsigned long arg)
@@ -49,9 +197,30 @@ static long privcmd_ioctl(struct file *file, unsigned int cmd,
return privcmd_hypercall(&cmd);
}
- case IOCTL_PRIVCMD_MMAP:
- case IOCTL_PRIVCMD_MMAPBATCH:
- printk(KERN_WARNING "IOCTL_PRIVCMD_MMAP ioctl not yet implemented\n");
+ case IOCTL_PRIVCMD_MMAP: {
+ privcmd_mmap_t cmd;
+
+ if (!is_initial_xendomain())
+ return -EPERM;
+
+ if (copy_from_user(&cmd, (void __user *)arg, sizeof(cmd)))
+ return -EFAULT;
+
+ return privcmd_mmap_cmd(&cmd);
+ }
+
+ case IOCTL_PRIVCMD_MMAPBATCH: {
+ privcmd_mmapbatch_t cmd;
+
+ if (!is_initial_xendomain())
+ return -EPERM;
+
+ if (copy_from_user(&cmd, (void __user *)arg, sizeof(cmd)))
+ return -EFAULT;
+
+ return privcmd_mmap_batch_cmd(&cmd);
+ }
+
default:
return -EINVAL;
}
@@ -59,6 +228,7 @@ static long privcmd_ioctl(struct file *file, unsigned int cmd,
static const struct file_operations privcmd_file_ops = {
.unlocked_ioctl = privcmd_ioctl,
+ .mmap = privcmd_mmap,
};
int __init privcmd_create_proc_entry(void)
diff --git a/include/asm-x86/xen/hypervisor.h b/include/asm-x86/xen/hypervisor.h
index 8e15dd2..a266f4f 100644
--- a/include/asm-x86/xen/hypervisor.h
+++ b/include/asm-x86/xen/hypervisor.h
@@ -70,4 +70,8 @@ u64 jiffies_to_st(unsigned long jiffies);
#define is_running_on_xen() (xen_start_info ? 1 : 0)
+int xen_map_foreign_range(struct vm_area_struct *vma, unsigned long addr,
+ unsigned long mfn, unsigned long size,
+ pgprot_t prot, domid_t domid);
+
#endif /* __HYPERVISOR_H__ */
--
1.5.4.1
linux-2.6-acpi-eeepc-hotkey.patch:
--- NEW FILE linux-2.6-acpi-eeepc-hotkey.patch ---
Signed-off-by: Eric Cooper <ecc cmu edu>
---
drivers/misc/Kconfig | 10 +
drivers/misc/Makefile | 1 +
drivers/misc/eeepc.c | 447 +++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 458 insertions(+), 0 deletions(-)
create mode 100644 drivers/misc/eeepc.c
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index b1f9a40..8fd1ccb 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -251,4 +251,14 @@ config ATMEL_SSC
If unsure, say N.
+config EEEPC
+ tristate "Eee PC Hotkey Driver (EXPERIMENTAL)"
+ depends on X86
+ depends on ACPI
+ depends on EXPERIMENTAL && !ACPI_ASUS
+ ---help---
+ This driver supports the Fn-Fx keys on Eee PC laptops.
+
+ If you have an Eee PC laptop, say Y or M here.
+
endif # MISC_DEVICES
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 87f2685..699b35c 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -17,3 +17,4 @@ obj-$(CONFIG_SONY_LAPTOP) += sony-laptop.o
obj-$(CONFIG_THINKPAD_ACPI) += thinkpad_acpi.o
obj-$(CONFIG_FUJITSU_LAPTOP) += fujitsu-laptop.o
obj-$(CONFIG_EEPROM_93CX6) += eeprom_93cx6.o
+obj-$(CONFIG_EEEPC) += eeepc.o
diff --git a/drivers/misc/eeepc.c b/drivers/misc/eeepc.c
new file mode 100644
index 0000000..2e33117
--- /dev/null
+++ b/drivers/misc/eeepc.c
@@ -0,0 +1,447 @@
+/*
+ * eepc_acpi.c - Asus Eee PC hotkey driver
+ *
+ * Copyright (C) 2008 Eric Cooper <ecc cmu edu>
+ *
+ * Based on asus_acpi.c as patched for the Eee PC by Asus:
+ * ftp://ftp.asus.com/pub/ASUS/EeePC/701/ASUS_ACPI_071126.rar
+ *
+ * Copyright (C) 2002-2005 Julien Lerouge, 2003-2006 Karol Kozimor
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/platform_device.h>
+#include <acpi/acpi_drivers.h>
+#include <acpi/acpi_bus.h>
+#include <asm/uaccess.h>
+
+#define EEEPC_HOTK_NAME "Eee PC Hotkey Driver"
+#define EEEPC_HOTK_FILE "eeepc"
+#define EEEPC_HOTK_CLASS "hotkey"
+#define EEEPC_HOTK_DEVICE_NAME "Hotkey"
+#define EEEPC_HOTK_HID "ASUS010"
+
+#define EEEPC_LOG EEEPC_HOTK_FILE ": "
+#define EEEPC_ERR KERN_ERR EEEPC_LOG
+#define EEEPC_WARNING KERN_WARNING EEEPC_LOG
+#define EEEPC_NOTICE KERN_NOTICE EEEPC_LOG
+#define EEEPC_INFO KERN_INFO EEEPC_LOG
+
+/*
+ * Definitions for Asus EeePC
+ */
+
+#define NOTIFY_WLAN_ON 0x10
+
+enum {
+ DISABLE_ASL_WLAN = 0x0001,
+ DISABLE_ASL_BLUETOOTH = 0x0002,
+ DISABLE_ASL_IRDA = 0x0004,
+ DISABLE_ASL_CAMERA = 0x0008,
+ DISABLE_ASL_TV = 0x0010,
+ DISABLE_ASL_GPS = 0x0020,
+ DISABLE_ASL_DISPLAYSWITCH = 0x0040,
+ DISABLE_ASL_MODEM = 0x0080,
+ DISABLE_ASL_CARDREADER = 0x0100
+};
+
+enum {
+ CM_ASL_WLAN = 0,
+ CM_ASL_BLUETOOTH,
+ CM_ASL_IRDA,
+ CM_ASL_1394,
+ CM_ASL_CAMERA,
+ CM_ASL_TV,
+ CM_ASL_GPS,
+ CM_ASL_DVDROM,
+ CM_ASL_DISPLAYSWITCH,
+ CM_ASL_PANELBRIGHT,
+ CM_ASL_BIOSFLASH,
+ CM_ASL_ACPIFLASH,
+ CM_ASL_CPUFV,
+ CM_ASL_CPUTEMPERATURE,
+ CM_ASL_FANCPU,
+ CM_ASL_FANCHASSIS,
+ CM_ASL_USBPORT1,
+ CM_ASL_USBPORT2,
+ CM_ASL_USBPORT3,
+ CM_ASL_MODEM,
+ CM_ASL_CARDREADER,
+ CM_ASL_LID
+};
+
+const char *cm_getv[] = {
+ "WLDG", NULL, NULL, NULL,
+ "CAMG", NULL, NULL, NULL,
+ NULL, "PBLG", NULL, NULL,
+ "CFVG", NULL, NULL, NULL,
+ "USBG", NULL, NULL, "MODG",
+ "CRDG", "LIDG"
+};
+
+const char *cm_setv[] = {
+ "WLDS", NULL, NULL, NULL,
+ "CAMS", NULL, NULL, NULL,
+ "SDSP", "PBLS", "HDPS", NULL,
+ "CFVS", NULL, NULL, NULL,
+ "USBG", NULL, NULL, "MODS",
+ "CRDS", NULL
+};
+
+static unsigned int init_flag;
+
+/*
+ * This is the main structure, we can use it to store useful information
+ * about the hotk device
+ */
+struct eeepc_hotk {
+ struct acpi_device *device; /* the device we are in */
+ acpi_handle handle; /* the handle of the hotk device */
+ u32 cm_supported; /* the control methods supported
+ by this BIOS */
+ u16 event_count[128]; /* count for each event */
+};
+
+/* The actual device the driver binds to */
+static struct eeepc_hotk *ehotk;
+
+/*
+ * The hotkey driver declaration
+ */
+static int eeepc_hotk_add(struct acpi_device *device);
+static int eeepc_hotk_remove(struct acpi_device *device, int type);
+
+static const struct acpi_device_id eee_device_ids[] = {
+ {EEEPC_HOTK_HID, 0},
+ {"", 0},
+};
+
+static struct acpi_driver eeepc_hotk_driver = {
+ .name = EEEPC_HOTK_NAME,
+ .class = EEEPC_HOTK_CLASS,
+ .ids = eee_device_ids,
+ .ops = {
+ .add = eeepc_hotk_add,
+ .remove = eeepc_hotk_remove,
+ },
+};
+
+MODULE_AUTHOR("Julien Lerouge, Karol Kozimor, Eric Cooper");
+MODULE_DESCRIPTION(EEEPC_HOTK_NAME);
+MODULE_LICENSE("GPL");
+
+/*
+ * returns 1 if write is successful, otherwise 0.
+ */
+static int write_acpi_int(acpi_handle handle, const char *method, int val,
+ struct acpi_buffer *output)
+{
+ struct acpi_object_list params;
+ union acpi_object in_obj;
+ acpi_status status;
+
+ params.count = 1;
+ params.pointer = &in_obj;
+ in_obj.type = ACPI_TYPE_INTEGER;
+ in_obj.integer.value = val;
+
+ status = acpi_evaluate_object(handle, (char *)method, ¶ms, output);
+ return (status == AE_OK);
+}
+
+static int read_acpi_int(acpi_handle handle, const char *method, int *val)
+{
+ struct acpi_buffer output;
+ union acpi_object out_obj;
+ acpi_status status;
+
+ output.length = sizeof(out_obj);
+ output.pointer = &out_obj;
+ status = acpi_evaluate_object(handle, (char *) method, NULL, &output);
+ *val = out_obj.integer.value;
+ return (status == AE_OK) && (out_obj.type == ACPI_TYPE_INTEGER);
+}
+
+static int parse_arg(const char *buf, unsigned long count, int *val)
+{
+ if (!count)
+ return 0;
+ if (count > 31)
+ return -EINVAL;
+ if (sscanf(buf, "%i", val) != 1)
+ return -EINVAL;
+ return count;
+}
+
+static ssize_t store_proc(int cm, const char *buf, size_t count)
+{
+ int rv, value;
+
+ rv = parse_arg(buf, count, &value);
+ if (rv > 0 && (ehotk->cm_supported & (0x1 << cm))) {
+ const char *method = cm_setv[cm];
+ if (method == NULL)
+ return 0;
+ if (!write_acpi_int(ehotk->handle, method, value, NULL))
+ printk(EEEPC_WARNING "Error writing %s\n", method);
+ }
+ return rv;
+}
+
+static ssize_t show_proc(int cm, char *buf)
+{
+ int value = -1;
+
+ if ((ehotk->cm_supported & (0x1 << cm))) {
+ const char *method = cm_getv[cm];
+ if (method == NULL)
+ return 0;
+ if (!read_acpi_int(ehotk->handle, method, &value))
+ printk(EEEPC_WARNING "Error reading %s\n", method);
+ }
+ return sprintf(buf, "%d\n", value);
+}
+
+static ssize_t real_store_init(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int rv, value;
+
+ rv = parse_arg(buf, count, &value);
+ if (!write_acpi_int(ehotk->handle, "INIT", value, NULL))
+ printk(EEEPC_ERR "Hotkey initialization failed\n");
+ else
+ printk(EEEPC_INFO "Reset init flag 0x%x\n", value);
+ return rv;
+}
+
+#define EEEPC_CREATE_DEVICE_ATTR(_name, _cm) \
+ static ssize_t show_##_name(struct device *dev, \
+ struct device_attribute *attr, \
+ char *buf) \
+ { \
+ return show_proc(_cm, buf); \
+ } \
+ static ssize_t store_##_name(struct device *dev, \
+ struct device_attribute *attr, \
+ const char *buf, size_t count) \
+ { \
+ return store_proc(_cm, buf, count); \
+ } \
+ static struct device_attribute dev_attr_##_name = { \
+ .attr = { \
+ .name = __stringify(_name), \
+ .mode = 0644 }, \
+ .show = show_##_name, \
+ .store = store_##_name, \
+ }
+
+EEEPC_CREATE_DEVICE_ATTR(brn, CM_ASL_PANELBRIGHT);
+EEEPC_CREATE_DEVICE_ATTR(camera, CM_ASL_CAMERA);
+EEEPC_CREATE_DEVICE_ATTR(cardr, CM_ASL_CARDREADER);
+EEEPC_CREATE_DEVICE_ATTR(cpufv, CM_ASL_CPUFV);
+EEEPC_CREATE_DEVICE_ATTR(disp, CM_ASL_DISPLAYSWITCH);
+EEEPC_CREATE_DEVICE_ATTR(hdps, CM_ASL_BIOSFLASH);
+EEEPC_CREATE_DEVICE_ATTR(init, -1); /* fixed up in eeepc_hotk_add() */
+EEEPC_CREATE_DEVICE_ATTR(lid, CM_ASL_LID);
+EEEPC_CREATE_DEVICE_ATTR(wlan, CM_ASL_WLAN);
+
+static struct attribute *platform_attributes[] = {
+ &dev_attr_brn.attr,
+ &dev_attr_camera.attr,
+ &dev_attr_cardr.attr,
+ &dev_attr_cpufv.attr,
+ &dev_attr_disp.attr,
+ &dev_attr_hdps.attr,
+ &dev_attr_init.attr,
+ &dev_attr_lid.attr,
+ &dev_attr_wlan.attr,
+ NULL
+};
+
+static struct attribute_group platform_attribute_group = {
+ .attrs = platform_attributes
+};
+
+static int eeepc_hotk_check(void)
+{
+ struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
+ int result;
+
+ result = acpi_bus_get_status(ehotk->device);
+ if (result)
+ return result;
+ if (ehotk->device->status.present) {
+ if (!write_acpi_int(ehotk->handle, "INIT", init_flag,
+ &buffer)) {
+ printk(EEEPC_ERR "Hotkey initialization failed\n");
+ return -ENODEV;
+ } else {
+ printk(EEEPC_NOTICE "Hotkey init flags 0x%x\n",
+ init_flag);
+ }
+ /* get control methods supported */
+ if (!read_acpi_int(ehotk->handle, "CMSG"
+ , &ehotk->cm_supported)) {
+ printk(EEEPC_ERR
+ "Get control methods supported failed\n");
+ return -ENODEV;
+ } else {
+ printk(EEEPC_INFO
+ "Get control methods supported: 0x%x\n",
+ ehotk->cm_supported);
+ }
+ ehotk->cm_supported |= (0x1 << CM_ASL_LID);
+ } else {
+ printk(EEEPC_ERR "Hotkey device not present, aborting\n");
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static void eeepc_hotk_notify(acpi_handle handle, u32 event, void *data)
+{
+ if (!ehotk)
+ return;
+ /* if DISABLE_ASL_WLAN is set, the notify code for fn+f2
+ will always be 0x10 */
+ if (event == NOTIFY_WLAN_ON && (DISABLE_ASL_WLAN & init_flag)) {
+ int value;
+ if (ehotk->cm_supported & (0x1 << CM_ASL_WLAN)) {
+ const char *method = cm_getv[CM_ASL_WLAN];
+ if (!read_acpi_int(ehotk->handle, method, &value))
+ printk(EEEPC_WARNING "Error reading %s\n",
+ method);
+ else if (value == 1)
+ event = 0x11;
+ }
+ }
+ acpi_bus_generate_proc_event(ehotk->device, event,
+ ehotk->event_count[event % 128]++);
+}
+
+static int ehotk_found;
+
+static int eeepc_hotk_add(struct acpi_device *device)
+{
+ acpi_status status = AE_OK;
+ int result;
+
+ if (!device)
+ return -EINVAL;
+ printk(EEEPC_NOTICE EEEPC_HOTK_NAME "\n");
+ ehotk = kzalloc(sizeof(struct eeepc_hotk), GFP_KERNEL);
+ if (!ehotk)
+ return -ENOMEM;
+ ehotk->handle = device->handle;
+ strcpy(acpi_device_name(device), EEEPC_HOTK_DEVICE_NAME);
+ strcpy(acpi_device_class(device), EEEPC_HOTK_CLASS);
+ acpi_driver_data(device) = ehotk;
+ ehotk->device = device;
+ result = eeepc_hotk_check();
+ if (result)
+ goto end;
+ dev_attr_init.show = NULL;
+ dev_attr_init.store = real_store_init;
+ status = acpi_install_notify_handler(ehotk->handle, ACPI_SYSTEM_NOTIFY,
+ eeepc_hotk_notify, ehotk);
+ if (ACPI_FAILURE(status))
+ printk(EEEPC_ERR "Error installing notify handler\n");
+ ehotk_found = 1;
+ end:
+ if (result)
+ kfree(ehotk);
+ return result;
+}
+
+static int eeepc_hotk_remove(struct acpi_device *device, int type)
+{
+ acpi_status status = 0;
+
+ if (!device || !acpi_driver_data(device))
+ return -EINVAL;
+ status = acpi_remove_notify_handler(ehotk->handle, ACPI_SYSTEM_NOTIFY,
+ eeepc_hotk_notify);
+ if (ACPI_FAILURE(status))
+ printk(EEEPC_ERR "Error removing notify handler\n");
+ kfree(ehotk);
+ return 0;
+}
+
+static struct platform_driver platform_driver = {
+ .driver = {
+ .name = EEEPC_HOTK_FILE,
+ .owner = THIS_MODULE,
+ }
+};
+
+static struct platform_device *platform_device;
+
+static void __exit eeepc_hotk_exit(void)
+{
+ acpi_bus_unregister_driver(&eeepc_hotk_driver);
+ sysfs_remove_group(&platform_device->dev.kobj,
+ &platform_attribute_group);
+ platform_device_unregister(platform_device);
+ platform_driver_unregister(&platform_driver);
+}
+
+static int __init eeepc_hotk_init(void)
+{
+ struct device *dev;
+ int result;
+
+ if (acpi_disabled)
+ return -ENODEV;
+ init_flag = DISABLE_ASL_WLAN | DISABLE_ASL_DISPLAYSWITCH;
+ result = acpi_bus_register_driver(&eeepc_hotk_driver);
+ if (result < 0)
+ return result;
+ if (!ehotk_found) {
+ acpi_bus_unregister_driver(&eeepc_hotk_driver);
+ return -ENODEV;
+ }
+ dev = acpi_get_physical_device(ehotk->device->handle);
+ /* Register platform stuff */
+ result = platform_driver_register(&platform_driver);
+ if (result)
+ goto fail_platform_driver;
+ platform_device = platform_device_alloc(EEEPC_HOTK_FILE, -1);
+ if (!platform_device) {
+ result = -ENOMEM;
+ goto fail_platform_device1;
+ }
+ result = platform_device_add(platform_device);
+ if (result)
+ goto fail_platform_device2;
+ result = sysfs_create_group(&platform_device->dev.kobj,
+ &platform_attribute_group);
+ if (result)
+ goto fail_sysfs;
+ return 0;
+ fail_sysfs:
+ platform_device_del(platform_device);
+ fail_platform_device2:
+ platform_device_put(platform_device);
+ fail_platform_device1:
+ platform_driver_unregister(&platform_driver);
+ fail_platform_driver:
+ return result;
+}
+
+module_init(eeepc_hotk_init);
+module_exit(eeepc_hotk_exit);
linux-2.6-agp-mm.patch:
--- NEW FILE linux-2.6-agp-mm.patch ---
diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c
index 42ba0e2..103b9df 100644
--- a/arch/x86/pci/i386.c
+++ b/arch/x86/pci/i386.c
@@ -72,7 +72,7 @@ pcibios_align_resource(void *data, struct resource *res,
}
}
}
-
+EXPORT_SYMBOL(pcibios_align_resource);
/*
* Handle resources of PCI devices. If the world were perfect, we could
diff --git a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h
index b83824c..9ec9374 100644
--- a/drivers/char/agp/agp.h
+++ b/drivers/char/agp/agp.h
@@ -117,7 +117,8 @@ struct agp_bridge_driver {
void (*free_by_type)(struct agp_memory *);
void *(*agp_alloc_page)(struct agp_bridge_data *);
void (*agp_destroy_page)(void *, int flags);
- int (*agp_type_to_mask_type) (struct agp_bridge_data *, int);
+ int (*agp_type_to_mask_type) (struct agp_bridge_data *, int);
+ void (*chipset_flush)(struct agp_bridge_data *);
};
struct agp_bridge_data {
diff --git a/drivers/char/agp/backend.c b/drivers/char/agp/backend.c
index 832ded2..f9c180c 100644
--- a/drivers/char/agp/backend.c
+++ b/drivers/char/agp/backend.c
@@ -43,7 +43,7 @@
* fix some real stupidity. It's only by chance we can bump
* past 0.99 at all due to some boolean logic error. */
#define AGPGART_VERSION_MAJOR 0
-#define AGPGART_VERSION_MINOR 102
+#define AGPGART_VERSION_MINOR 103
static const struct agp_version agp_current_version =
{
.major = AGPGART_VERSION_MAJOR,
diff --git a/drivers/char/agp/compat_ioctl.c b/drivers/char/agp/compat_ioctl.c
index ecd4248..3927579 100644
--- a/drivers/char/agp/compat_ioctl.c
+++ b/drivers/char/agp/compat_ioctl.c
@@ -273,6 +273,10 @@ long compat_agp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
case AGPIOC_UNBIND32:
ret_val = compat_agpioc_unbind_wrap(curr_priv, (void __user *) arg);
break;
+
+ case AGPIOC_CHIPSET_FLUSH32:
+ ret_val = agpioc_chipset_flush_wrap(curr_priv);
+ break;
}
ioctl_out:
diff --git a/drivers/char/agp/compat_ioctl.h b/drivers/char/agp/compat_ioctl.h
index 71939d6..0c9678a 100644
--- a/drivers/char/agp/compat_ioctl.h
+++ b/drivers/char/agp/compat_ioctl.h
@@ -39,6 +39,7 @@
#define AGPIOC_DEALLOCATE32 _IOW (AGPIOC_BASE, 7, compat_int_t)
#define AGPIOC_BIND32 _IOW (AGPIOC_BASE, 8, compat_uptr_t)
#define AGPIOC_UNBIND32 _IOW (AGPIOC_BASE, 9, compat_uptr_t)
+#define AGPIOC_CHIPSET_FLUSH32 _IO (AGPIOC_BASE, 10)
struct agp_info32 {
struct agp_version version; /* version of the driver */
@@ -101,5 +102,6 @@ void agp_free_memory_wrap(struct agp_memory *memory);
struct agp_memory *agp_allocate_memory_wrap(size_t pg_count, u32 type);
struct agp_memory *agp_find_mem_by_key(int key);
struct agp_client *agp_find_client_by_pid(pid_t id);
+int agpioc_chipset_flush_wrap(struct agp_file_private *priv);
#endif /* _AGP_COMPAT_H */
diff --git a/drivers/char/agp/frontend.c b/drivers/char/agp/frontend.c
index 7791e98..9bd5a95 100644
--- a/drivers/char/agp/frontend.c
+++ b/drivers/char/agp/frontend.c
@@ -960,6 +960,13 @@ static int agpioc_unbind_wrap(struct agp_file_private *priv, void __user *arg)
return agp_unbind_memory(memory);
}
+int agpioc_chipset_flush_wrap(struct agp_file_private *priv)
+{
+ DBG("");
+ agp_flush_chipset(agp_bridge);
+ return 0;
+}
+
static int agp_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
@@ -1033,6 +1040,10 @@ static int agp_ioctl(struct inode *inode, struct file *file,
case AGPIOC_UNBIND:
ret_val = agpioc_unbind_wrap(curr_priv, (void __user *) arg);
break;
+
+ case AGPIOC_CHIPSET_FLUSH:
+ ret_val = agpioc_chipset_flush_wrap(curr_priv);
+ break;
}
ioctl_out:
diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c
index 64b2f6d..8c67b4f 100644
--- a/drivers/char/agp/generic.c
+++ b/drivers/char/agp/generic.c
@@ -80,6 +80,13 @@ static int agp_get_key(void)
return -1;
}
+void agp_flush_chipset(struct agp_bridge_data *bridge)
+{
+ if (bridge->driver->chipset_flush)
+ bridge->driver->chipset_flush(bridge);
+}
+EXPORT_SYMBOL(agp_flush_chipset);
+
/*
* Use kmalloc if possible for the page list. Otherwise fall back to
* vmalloc. This speeds things up and also saves memory for small AGP
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
index d879619..f161d15 100644
--- a/drivers/char/agp/intel-agp.c
+++ b/drivers/char/agp/intel-agp.c
@@ -69,9 +69,11 @@ extern int agp_memory_reserved;
#define I915_GMCH_GMS_STOLEN_64M (0x7 << 4)
#define G33_GMCH_GMS_STOLEN_128M (0x8 << 4)
#define G33_GMCH_GMS_STOLEN_256M (0x9 << 4)
+#define I915_IFPADDR 0x60
/* Intel 965G registers */
#define I965_MSAC 0x62
+#define I965_IFPADDR 0x70
/* Intel 7505 registers */
#define INTEL_I7505_APSIZE 0x74
@@ -113,6 +115,12 @@ static struct _intel_private {
* popup and for the GTT.
*/
int gtt_entries; /* i830+ */
+ union {
+ void __iomem *i9xx_flush_page;
+ void *i8xx_flush_page;
+ };
+ struct page *i8xx_page;
+ struct resource ifp_resource;
} intel_private;
static int intel_i810_fetch_size(void)
@@ -576,6 +584,44 @@ static void intel_i830_init_gtt_entries(void)
intel_private.gtt_entries = gtt_entries;
}
+static void intel_i830_fini_flush(void)
+{
+ kunmap(intel_private.i8xx_page);
+ intel_private.i8xx_flush_page = NULL;
+ unmap_page_from_agp(intel_private.i8xx_page);
+ flush_agp_mappings();
+
+ __free_page(intel_private.i8xx_page);
+}
+
+static void intel_i830_setup_flush(void)
+{
+
+ intel_private.i8xx_page = alloc_page(GFP_KERNEL | __GFP_ZERO | GFP_DMA32);
+ if (!intel_private.i8xx_page) {
+ return;
+ }
+
+ /* make page uncached */
+ map_page_into_agp(intel_private.i8xx_page);
+ flush_agp_mappings();
+
+ intel_private.i8xx_flush_page = kmap(intel_private.i8xx_page);
+ if (!intel_private.i8xx_flush_page)
+ intel_i830_fini_flush();
+}
+
+static void intel_i830_chipset_flush(struct agp_bridge_data *bridge)
+{
+ unsigned int *pg = intel_private.i8xx_flush_page;
+ int i;
+
+ for (i = 0; i < 256; i+=2)
+ *(pg + i) = i;
+
+ wmb();
+}
+
/* The intel i830 automatically initializes the agp aperture during POST.
* Use the memory already set aside for in the GTT.
*/
@@ -676,6 +722,8 @@ static int intel_i830_configure(void)
}
global_cache_flush();
+
+ intel_i830_setup_flush();
return 0;
}
@@ -769,6 +817,90 @@ static struct agp_memory *intel_i830_alloc_by_type(size_t pg_count,int type)
return NULL;
}
+static int intel_alloc_chipset_flush_resource(void)
+{
+ int ret;
+ ret = pci_bus_alloc_resource(agp_bridge->dev->bus, &intel_private.ifp_resource, PAGE_SIZE,
+ PAGE_SIZE, PCIBIOS_MIN_MEM, 0,
+ pcibios_align_resource, agp_bridge->dev);
+
+ return ret;
+}
+
+static void intel_i915_setup_chipset_flush(void)
+{
+ int ret;
+ u32 temp;
+
+ pci_read_config_dword(agp_bridge->dev, I915_IFPADDR, &temp);
+ if (!(temp & 0x1)) {
+ intel_alloc_chipset_flush_resource();
+
+ pci_write_config_dword(agp_bridge->dev, I915_IFPADDR, (intel_private.ifp_resource.start & 0xffffffff) | 0x1);
+ } else {
+ temp &= ~1;
+
+ intel_private.ifp_resource.start = temp;
+ intel_private.ifp_resource.end = temp + PAGE_SIZE;
+ ret = request_resource(&iomem_resource, &intel_private.ifp_resource);
+ if (ret) {
+ intel_private.ifp_resource.start = 0;
+ printk("Failed inserting resource into tree\n");
+ }
+ }
+}
+
+static void intel_i965_g33_setup_chipset_flush(void)
+{
+ u32 temp_hi, temp_lo;
+ int ret;
+
+ pci_read_config_dword(agp_bridge->dev, I965_IFPADDR + 4, &temp_hi);
+ pci_read_config_dword(agp_bridge->dev, I965_IFPADDR, &temp_lo);
+
+ if (!(temp_lo & 0x1)) {
+
+ intel_alloc_chipset_flush_resource();
+
+ pci_write_config_dword(agp_bridge->dev, I965_IFPADDR + 4, (intel_private.ifp_resource.start >> 32));
+ pci_write_config_dword(agp_bridge->dev, I965_IFPADDR, (intel_private.ifp_resource.start & 0xffffffff) | 0x1);
+ } else {
+ u64 l64;
+
+ temp_lo &= ~0x1;
+ l64 = ((u64)temp_hi << 32) | temp_lo;
+
+ intel_private.ifp_resource.start = l64;
+ intel_private.ifp_resource.end = l64 + PAGE_SIZE;
+ ret = request_resource(&iomem_resource, &intel_private.ifp_resource);
+ if (!ret) {
+ printk("Failed inserting resource into tree - continuing\n");
+ }
+ }
+}
+
+static void intel_i9xx_setup_flush(void)
+{
+ /* setup a resource for this object */
+ memset(&intel_private.ifp_resource, 0, sizeof(intel_private.ifp_resource));
+
+ intel_private.ifp_resource.name = "Intel Flush Page";
+ intel_private.ifp_resource.flags = IORESOURCE_MEM;
+
+ /* Setup chipset flush for 915 */
+ if (IS_I965 || IS_G33) {
+ intel_i965_g33_setup_chipset_flush();
+ } else {
+ intel_i915_setup_chipset_flush();
+ }
+
+ if (intel_private.ifp_resource.start) {
+ intel_private.i9xx_flush_page = ioremap_nocache(intel_private.ifp_resource.start, PAGE_SIZE);
+ if (!intel_private.i9xx_flush_page)
+ printk("unable to ioremap flush page - no chipset flushing");
+ }
+}
+
static int intel_i915_configure(void)
{
struct aper_size_info_fixed *current_size;
@@ -797,15 +929,26 @@ static int intel_i915_configure(void)
}
global_cache_flush();
+
+ intel_i9xx_setup_flush();
+
return 0;
}
static void intel_i915_cleanup(void)
{
+ if (intel_private.i9xx_flush_page)
+ iounmap(intel_private.i9xx_flush_page);
iounmap(intel_private.gtt);
iounmap(intel_private.registers);
}
+static void intel_i915_chipset_flush(struct agp_bridge_data *bridge)
+{
+ if (intel_private.i9xx_flush_page)
+ writel(1, intel_private.i9xx_flush_page);
+}
+
static int intel_i915_insert_entries(struct agp_memory *mem,off_t pg_start,
int type)
{
@@ -1297,6 +1440,8 @@ static int intel_845_configure(void)
pci_write_config_byte(agp_bridge->dev, INTEL_I845_AGPM, temp2 | (1 << 1));
/* clear any possible error conditions */
pci_write_config_word(agp_bridge->dev, INTEL_I845_ERRSTS, 0x001c);
+
+ intel_i830_setup_flush();
return 0;
}
@@ -1553,6 +1698,7 @@ static const struct agp_bridge_driver intel_830_driver = {
.agp_alloc_page = agp_generic_alloc_page,
.agp_destroy_page = agp_generic_destroy_page,
.agp_type_to_mask_type = intel_i830_type_to_mask_type,
+ .chipset_flush = intel_i830_chipset_flush,
};
static const struct agp_bridge_driver intel_820_driver = {
@@ -1649,6 +1795,7 @@ static const struct agp_bridge_driver intel_845_driver = {
.agp_alloc_page = agp_generic_alloc_page,
.agp_destroy_page = agp_generic_destroy_page,
.agp_type_to_mask_type = agp_generic_type_to_mask_type,
+ .chipset_flush = intel_i830_chipset_flush,
};
static const struct agp_bridge_driver intel_850_driver = {
@@ -1722,6 +1869,7 @@ static const struct agp_bridge_driver intel_915_driver = {
.agp_alloc_page = agp_generic_alloc_page,
.agp_destroy_page = agp_generic_destroy_page,
.agp_type_to_mask_type = intel_i830_type_to_mask_type,
+ .chipset_flush = intel_i915_chipset_flush,
};
static const struct agp_bridge_driver intel_i965_driver = {
@@ -1747,6 +1895,7 @@ static const struct agp_bridge_driver intel_i965_driver = {
.agp_alloc_page = agp_generic_alloc_page,
.agp_destroy_page = agp_generic_destroy_page,
.agp_type_to_mask_type = intel_i830_type_to_mask_type,
+ .chipset_flush = intel_i915_chipset_flush,
};
static const struct agp_bridge_driver intel_7505_driver = {
@@ -1796,6 +1945,7 @@ static const struct agp_bridge_driver intel_g33_driver = {
.agp_alloc_page = agp_generic_alloc_page,
.agp_destroy_page = agp_generic_destroy_page,
.agp_type_to_mask_type = intel_i830_type_to_mask_type,
+ .chipset_flush = intel_i915_chipset_flush,
};
static int find_gmch(u16 device)
diff --git a/include/linux/agp_backend.h b/include/linux/agp_backend.h
index abc521c..03e3454 100644
--- a/include/linux/agp_backend.h
+++ b/include/linux/agp_backend.h
@@ -109,6 +109,7 @@ extern int agp_unbind_memory(struct agp_memory *);
extern void agp_enable(struct agp_bridge_data *, u32);
extern struct agp_bridge_data *agp_backend_acquire(struct pci_dev *);
extern void agp_backend_release(struct agp_bridge_data *);
+extern void agp_flush_chipset(struct agp_bridge_data *);
#endif /* __KERNEL__ */
#endif /* _AGP_BACKEND_H */
diff --git a/include/linux/agpgart.h b/include/linux/agpgart.h
index 09fbf7e..62aef58 100644
--- a/include/linux/agpgart.h
+++ b/include/linux/agpgart.h
@@ -38,6 +38,7 @@
#define AGPIOC_DEALLOCATE _IOW (AGPIOC_BASE, 7, int)
#define AGPIOC_BIND _IOW (AGPIOC_BASE, 8, struct agp_bind*)
#define AGPIOC_UNBIND _IOW (AGPIOC_BASE, 9, struct agp_unbind*)
+#define AGPIOC_CHIPSET_FLUSH _IO (AGPIOC_BASE, 10)
#define AGP_DEVICE "/dev/agpgart"
linux-2.6-alsa-rc4-mm1.patch:
--- NEW FILE linux-2.6-alsa-rc4-mm1.patch ---
GIT a7789dbc42abf8efbfdd46b99ffa39b4404f7184 git+ssh://master.kernel.org/pub/scm/linux/kernel/git/perex/alsa.git#mm
commit
Author: Takashi Iwai <tiwai suse de>
Date: Mon Dec 3 17:08:40 2007 +0100
[ALSA] echoaudio - convert from semaphore to mutex
Converted from semaphore to mutex.
Signed-off-by: Takashi Iwai <tiwai suse de>
Signed-off-by: Jaroslav Kysela <perex perex cz>
commit 78c3ffce0da390847c18daabfe49d4d457b2149f
Author: Andy Shevchenko <andy smile org ua>
Date: Mon Dec 3 16:50:58 2007 +0100
[ALSA] hda-codec - Fix typo in the ALC883 initial code
The attached patch should fix typo in auto initialization verbs for ALC883
codec.
Signed-off-by: Andy Shevchenko <andy smile org ua>
Signed-off-by: Takashi Iwai <tiwai suse de>
Signed-off-by: Jaroslav Kysela <perex perex cz>
commit 91f02c16c74a1c151682ce4a33f9548e3227e4d0
Author: Pavel Hofman <dustin seznam cz>
Date: Mon Dec 3 12:44:28 2007 +0100
[ALSA] switching rate in STAC9460 codec of Prodigy192
* support for switching rate in STAC9460 - using set_rate_val of the akm
infrastructure
* listing all STAC9460 registers in proc
* disabling mpu401 device for Prodigy192 - otherwise the currently
flawed mpu401 code hangs kernel when opening the midi device
* removing old unused commented-out code
Signed-off-by: Pavel Hofman <dustin seznam cz>
Signed-off-by: Takashi Iwai <tiwai suse de>
Signed-off-by: Jaroslav Kysela <perex perex cz>
commit 35b3a3c38a2a18c00e8e8f99fc1cb2dadf9eebd1
Author: Pavel Hofman <dustin seznam cz>
Date: Mon Dec 3 12:37:17 2007 +0100
[ALSA] I2C fix for ice1724
adding i2c busy wait before sending device address to prevent reading
bogus data.
Signed-off-by: Pavel Hofman <dustin seznam cz>
Signed-off-by: Takashi Iwai <tiwai suse de>
Signed-off-by: Jaroslav Kysela <perex perex cz>
commit f9129a53abcdfd700eef783d8179c4ce39dc0482
Author: Rene Herman <rene herman gmail com>
Date: Fri Nov 30 17:59:25 2007 +0100
[ALSA] sound/isa: kill pnp_resource_change
This removes the pnp_resource_change use from the ALSA ISAPnP drivers. In
2.4 these were useful in providing an easy path to setting the resources,
but in 2.6 they retain function as a layering violation only.
This makes for a nice cleanup (-550 lines) of ALSA but moreover, ALSA is the
only remaining user of pnp_init_resource_table(), pnp_resource_change() and
pnp_manual_config_dev() (and, in fact, of 'struct pnp_resource_table') in
the tree outide of drivers/pnp itself meaning it makes for more cleanup
potential inside the PnP layer.
Thomas Renninger acked their removal from that side, you did from the ALSA
side (CC list just copied from that thread).
Against current alsa-kernel HG. Many more potential cleanups in there, but
this _only_ removes the pnp_resource_change code. Compile tested against
current alsa-kernel HG and compile- and use-tested against 2.6.23.x (few
offsets).
Cc: Thomas Renninger <trenn suse de>
Signed-off-by: Rene Herman <rene herman gmail com>
Signed-off-by: Takashi Iwai <tiwai suse de>
Signed-off-by: Jaroslav Kysela <perex perex cz>
commit da1cd2b5d7168e630972565308fd4207440ad3e6
Author: Julia Lawall <julia diku dk>
Date: Wed Nov 28 11:58:56 2007 +0100
[ALSA] sound/core/memalloc.c: Add missing pci_dev_put
There should be a pci_dev_put when breaking out of a loop that iterates
over calls to pci_get_device and similar functions.
In this case, the return under the initial if needs a pci_dev_put in the
same way that the return under the subsequent for loop has a pci_dev_put.
This was fixed using the following semantic patch.
// <smpl>
@@
type T;
identifier d;
expression e;
@@
T *d;
...
while ((d = \(pci_get_device\|pci_get_device_reverse\|pci_get_subsys\|pci_get_class\)(..., d)) != NULL)
{... when != pci_dev_put(d)
when != e = d
(
return d;
|
+ pci_dev_put(d);
? return ...;
)
...}
// </smpl>
Signed-off-by: Julia Lawall <julia diku dk>
Signed-off-by: Andrew Morton <akpm linux-foundation org>
Signed-off-by: Takashi Iwai <tiwai suse de>
Signed-off-by: Jaroslav Kysela <perex perex cz>
commit 43ee07cf0d4e3fe542626a5347e9c6161beb7f2c
Author: Takashi Iwai <tiwai suse de>
Date: Tue Nov 27 15:27:17 2007 +0100
[ALSA] ice1712 - Fix word clock status control on Delta 1010LT
The 'Word Clock Status' control on Delta 1010LT checks the CS8427
error register too strictly and almost always returns 1 (unlocked).
It should check only the lock status bit.
Signed-off-by: Takashi Iwai <tiwai suse de>
Signed-off-by: Jaroslav Kysela <perex perex cz>
commit 3e534c100d03b4abad7848508cab8daab29824fe
Author: Daniel Mack <daniel caiaq de>
Date: Mon Nov 26 09:00:56 2007 +0100
[ALSA] usb-caiaq - add support for Kore controller 2
Added support for Native Instrument's Kore controller 2. This device has
no audio but MIDI, input devices and ALSA controllers only.
Signed-off-by: Daniel Mack <daniel caiaq de>
Signed-off-by: Takashi Iwai <tiwai suse de>
Signed-off-by: Jaroslav Kysela <perex perex cz>
commit 82982081f1b2412d6d8e7a8869436809cf2c4e18
Author: Ville Syrjala <syrjala sci fi>
Date: Mon Nov 26 08:58:24 2007 +0100
[ALSA] soc/wm8731: Fix stereo mixer controls
Disable the simultaneous load feature for the line in and headphone
out volume registers. This allows left and right volume levels to
be controlled separately.
Signed-off-by: Ville Syrjala <syrjala sci fi>
Signed-off-by: Takashi Iwai <tiwai suse de>
Signed-off-by: Jaroslav Kysela <perex perex cz>
commit 8e43d0d0c58a8705cb7c8fb5b5ec03efef8643f7
Author: Takashi Iwai <tiwai suse de>
Date: Mon Nov 26 08:58:48 2007 +0100
[ALSA] drivers - Add missing snd_card_set_dev()
Added the missing call of snd_card_set_dev() in drivers/*
Signed-off-by: Takashi Iwai <tiwai suse de>
Signed-off-by: Jaroslav Kysela <perex perex cz>
commit 8478fa3c825e1522cb516823090b1acc2c406af1
Author: Joe Perches <joe perches com>
Date: Mon Nov 26 08:44:15 2007 +0100
[ALSA] sound/isa: Add missing 'space'
Signed-off-by: Joe Perches <joe perches com>
Signed-off-by: Takashi Iwai <tiwai suse de>
Signed-off-by: Jaroslav Kysela <perex perex cz>
commit 27ab27100d74f0f5073fc8d50dea6aefffe20dda
Author: Takashi Iwai <tiwai suse de>
Date: Mon Nov 26 08:45:43 2007 +0100
[ALSA] emu10k1x - Add missing snd_card_set_dev call
Added the missing snd_card_set_dev() call. This will fix the incomplete
sysfs entry for this card.
Signed-off-by: Takashi Iwai <tiwai suse de>
Signed-off-by: Jaroslav Kysela <perex perex cz>
commit ca23210387b188bd6cbce13e644822cdbd148eac
Author: Takashi Iwai <tiwai suse de>
Date: Fri Nov 23 15:41:44 2007 +0100
[ALSA] aoa - fix compile warning
Set a proper error code in the error path of i2sbus_attach_codec().
[...21552 lines suppressed...]
input->keycodemax = ARRAY_SIZE(keycode_rk2);
- for (i=0; i<ARRAY_SIZE(keycode_rk2); i++)
- set_bit(keycode_rk2[i], input->keybit);
-
input_set_abs_params(input, ABS_X, 0, 4096, 0, 10);
input_set_abs_params(input, ABS_Y, 0, 4096, 0, 10);
input_set_abs_params(input, ABS_Z, 0, 4096, 0, 10);
snd_usb_caiaq_set_auto_msg(dev, 1, 10, 0);
break;
case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_RIGKONTROL3):
- input->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);
- input->absbit[0] = BIT(ABS_X) | BIT(ABS_Y) | BIT(ABS_Z);
- input->keycode = keycode_rk3;
- input->keycodesize = sizeof(char);
+ input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+ input->absbit[0] = BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) |
+ BIT_MASK(ABS_Z);
+ BUILD_BUG_ON(sizeof(dev->keycode) < sizeof(keycode_rk3));
+ memcpy(dev->keycode, keycode_rk3, sizeof(keycode_rk3));
input->keycodemax = ARRAY_SIZE(keycode_rk3);
- for (i=0; i<ARRAY_SIZE(keycode_rk3); i++)
- set_bit(keycode_rk3[i], input->keybit);
-
input_set_abs_params(input, ABS_X, 0, 1024, 0, 10);
input_set_abs_params(input, ABS_Y, 0, 1024, 0, 10);
input_set_abs_params(input, ABS_Z, 0, 1024, 0, 10);
@@ -231,21 +299,50 @@ int snd_usb_caiaq_input_init(struct snd_usb_caiaqdev *dev)
case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_AK1):
input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
input->absbit[0] = BIT_MASK(ABS_X);
- input->keycode = keycode_ak1;
- input->keycodesize = sizeof(char);
+ BUILD_BUG_ON(sizeof(dev->keycode) < sizeof(keycode_ak1));
+ memcpy(dev->keycode, keycode_ak1, sizeof(keycode_ak1));
input->keycodemax = ARRAY_SIZE(keycode_ak1);
- for (i=0; i<ARRAY_SIZE(keycode_ak1); i++)
- set_bit(keycode_ak1[i], input->keybit);
-
input_set_abs_params(input, ABS_X, 0, 999, 0, 10);
snd_usb_caiaq_set_auto_msg(dev, 1, 0, 5);
break;
+ case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER):
+ case USB_ID(USB_VID_NATIVEINSTRUMENTS, USB_PID_KORECONTROLLER2):
+ input->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+ input->absbit[0] = BIT_MASK(ABS_HAT0X) | BIT_MASK(ABS_HAT0Y) |
+ BIT_MASK(ABS_HAT1X) | BIT_MASK(ABS_HAT1Y) |
+ BIT_MASK(ABS_HAT2X) | BIT_MASK(ABS_HAT2Y) |
+ BIT_MASK(ABS_HAT3X) | BIT_MASK(ABS_HAT3Y) |
+ BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) |
+ BIT_MASK(ABS_Z);
+ input->absbit[BIT_WORD(ABS_MISC)] |= BIT_MASK(ABS_MISC);
+ BUILD_BUG_ON(sizeof(dev->keycode) < sizeof(keycode_kore));
+ memcpy(dev->keycode, keycode_kore, sizeof(keycode_kore));
+ input->keycodemax = ARRAY_SIZE(keycode_kore);
+ input_set_abs_params(input, ABS_HAT0X, 0, 999, 0, 10);
+ input_set_abs_params(input, ABS_HAT0Y, 0, 999, 0, 10);
+ input_set_abs_params(input, ABS_HAT1X, 0, 999, 0, 10);
+ input_set_abs_params(input, ABS_HAT1Y, 0, 999, 0, 10);
+ input_set_abs_params(input, ABS_HAT2X, 0, 999, 0, 10);
+ input_set_abs_params(input, ABS_HAT2Y, 0, 999, 0, 10);
+ input_set_abs_params(input, ABS_HAT3X, 0, 999, 0, 10);
+ input_set_abs_params(input, ABS_HAT3Y, 0, 999, 0, 10);
+ input_set_abs_params(input, ABS_X, 0, 4096, 0, 10);
+ input_set_abs_params(input, ABS_Y, 0, 4096, 0, 10);
+ input_set_abs_params(input, ABS_Z, 0, 4096, 0, 10);
+ input_set_abs_params(input, ABS_MISC, 0, 255, 0, 1);
+ snd_usb_caiaq_set_auto_msg(dev, 1, 10, 5);
+ break;
default:
/* no input methods supported on this device */
input_free_device(input);
return 0;
}
+ input->keycode = dev->keycode;
+ input->keycodesize = sizeof(unsigned short);
+ for (i = 0; i < input->keycodemax; i++)
+ __set_bit(dev->keycode[i], input->keybit);
+
ret = input_register_device(input);
if (ret < 0) {
input_free_device(input);
@@ -265,5 +362,3 @@ void snd_usb_caiaq_input_free(struct snd_usb_caiaqdev *dev)
dev->input_dev = NULL;
}
-#endif /* CONFIG_SND_USB_CAIAQ_INPUT */
-
diff --git a/sound/usb/usbmixer.c b/sound/usb/usbmixer.c
index 5e32969..1f1e91c 100644
--- a/sound/usb/usbmixer.c
+++ b/sound/usb/usbmixer.c
@@ -1703,6 +1703,11 @@ static void snd_usb_mixer_memory_change(struct usb_mixer_interface *mixer,
case 19: /* speaker out jacks */
case 20: /* headphones out jack */
break;
+ /* live24ext: 4 = line-in jack */
+ case 3: /* hp-out jack (may actuate Mute) */
+ if (mixer->chip->usb_id == USB_ID(0x041e, 0x3040))
+ snd_usb_mixer_notify_id(mixer, mixer->rc_cfg->mute_mixer_id);
+ break;
default:
snd_printd(KERN_DEBUG "memory change in unknown unit %d\n", unitid);
break;
@@ -1951,6 +1956,9 @@ static int snd_audigy2nx_controls_create(struct usb_mixer_interface *mixer)
int i, err;
for (i = 0; i < ARRAY_SIZE(snd_audigy2nx_controls); ++i) {
+ if (i > 1 && /* Live24ext has 2 LEDs only */
+ mixer->chip->usb_id == USB_ID(0x041e, 0x3040))
+ break;
err = snd_ctl_add(mixer->chip->card,
snd_ctl_new1(&snd_audigy2nx_controls[i], mixer));
if (err < 0)
@@ -1963,28 +1971,42 @@ static int snd_audigy2nx_controls_create(struct usb_mixer_interface *mixer)
static void snd_audigy2nx_proc_read(struct snd_info_entry *entry,
struct snd_info_buffer *buffer)
{
- static const struct {
+ static const struct sb_jack {
int unitid;
const char *name;
- } jacks[] = {
+ } jacks_audigy2nx[] = {
{4, "dig in "},
{7, "line in"},
{19, "spk out"},
{20, "hph out"},
+ {-1, NULL}
+ }, jacks_live24ext[] = {
+ {4, "line in"}, /* &1=Line, &2=Mic*/
+ {3, "hph out"}, /* headphones */
+ {0, "RC "}, /* last command, 6 bytes see rc_config above */
+ {-1, NULL}
};
+ const struct sb_jack *jacks;
struct usb_mixer_interface *mixer = entry->private_data;
int i, err;
u8 buf[3];
snd_iprintf(buffer, "%s jacks\n\n", mixer->chip->card->shortname);
- for (i = 0; i < ARRAY_SIZE(jacks); ++i) {
+ if (mixer->chip->usb_id == USB_ID(0x041e, 0x3020))
+ jacks = jacks_audigy2nx;
+ else if (mixer->chip->usb_id == USB_ID(0x041e, 0x3040))
+ jacks = jacks_live24ext;
+ else
+ return;
+
+ for (i = 0; jacks[i].name; ++i) {
snd_iprintf(buffer, "%s: ", jacks[i].name);
err = snd_usb_ctl_msg(mixer->chip->dev,
usb_rcvctrlpipe(mixer->chip->dev, 0),
GET_MEM, USB_DIR_IN | USB_TYPE_CLASS |
USB_RECIP_INTERFACE, 0,
jacks[i].unitid << 8, buf, 3, 100);
- if (err == 3 && buf[0] == 3)
+ if (err == 3 && (buf[0] == 3 || buf[0] == 6))
snd_iprintf(buffer, "%02x %02x\n", buf[1], buf[2]);
else
snd_iprintf(buffer, "?\n");
@@ -2022,7 +2044,8 @@ int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif)
if ((err = snd_usb_soundblaster_remote_init(mixer)) < 0)
goto _error;
- if (mixer->chip->usb_id == USB_ID(0x041e, 0x3020)) {
+ if (mixer->chip->usb_id == USB_ID(0x041e, 0x3020) ||
+ mixer->chip->usb_id == USB_ID(0x041e, 0x3040)) {
struct snd_info_entry *entry;
if ((err = snd_audigy2nx_controls_create(mixer)) < 0)
diff --git a/sound/usb/usbmixer_maps.c b/sound/usb/usbmixer_maps.c
index 7c4dcb3..d755be0 100644
--- a/sound/usb/usbmixer_maps.c
+++ b/sound/usb/usbmixer_maps.c
@@ -187,6 +187,13 @@ static struct usbmix_selector_map audigy2nx_selectors[] = {
{ 0 } /* terminator */
};
+/* Creative SoundBlaster Live! 24-bit External */
+static struct usbmix_name_map live24ext_map[] = {
+ /* 2: PCM Playback Volume */
+ { 5, "Mic Capture" }, /* FU, default PCM Capture Volume */
+ { 0 } /* terminator */
+};
+
/* LineX FM Transmitter entry - needed to bypass controls bug */
static struct usbmix_name_map linex_map[] = {
/* 1: IT pcm */
@@ -273,6 +280,10 @@ static struct usbmix_ctl_map usbmix_ctl_maps[] = {
.map = audigy2nx_map,
.selector_map = audigy2nx_selectors,
},
+ {
+ .id = USB_ID(0x041e, 0x3040),
+ .map = live24ext_map,
+ },
{
/* Hercules DJ Console (Windows Edition) */
.id = USB_ID(0x06f8, 0xb000),
linux-2.6-alsa-support-sis7019.patch:
--- NEW FILE linux-2.6-alsa-support-sis7019.patch ---
From: Dave Dillow <dave thedillows org>
Basic audio support for the SiS 7019 Audio Accelerator as found in the
SiS 55x SoC. There is currently no synth support at the moment, but
audio playback and capture with two periods per buffer has seen
extensive use. Arbitrary period and buffer sizes (with multiple periods
per buffer) have seen light testing, but are believed to be production
ready.
Signed-off-by: David Dillow <dave thedillows org>
---
This is against the alsa-kernel hg repo.
Changes since last posting:
* Removed unnecessary locking
* Added power management support
* Reworked capture period timing to use dedicated silence buffer
* Changed header location
* Fixed muting of left stereo channel
* Fixed XRUNs with non-integral periods per buffer
* Better enforcement of hardware limits
pci/sis7019.c | 1466 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
pci/sis7019.h | 342 +++++++++++++
pci/Kconfig | 10
pci/Makefile | 2
4 files changed, 1820 insertions(+)
diff -r 17223a4918b4 pci/Kconfig
--- a/sound/pci/Kconfig Tue Nov 27 15:27:17 2007 +0100
+++ b/sound/pci/Kconfig Wed Nov 28 01:39:33 2007 -0500
@@ -802,6 +802,16 @@ config SND_RME9652
To compile this driver as a module, choose M here: the module
will be called snd-rme9652.
+config SND_SIS7019
+ tristate "SiS 7019 Audio Accelerator"
+ depends on SND
+ select SND_AC97_CODEC
+ help
+ Say Y here to include support for the SiS 7019 Audio Accelerator.
+
+ To compile this driver as a module, choose M here: the module
+ will be called snd-sis7019.
+
config SND_SONICVIBES
tristate "S3 SonicVibes"
depends on SND
diff -r 17223a4918b4 pci/Makefile
--- a/sound/pci/Makefile Tue Nov 27 15:27:17 2007 +0100
+++ b/sound/pci/Makefile Wed Nov 28 01:39:33 2007 -0500
@@ -23,6 +23,7 @@ snd-maestro3-objs := maestro3.o
snd-maestro3-objs := maestro3.o
snd-rme32-objs := rme32.o
snd-rme96-objs := rme96.o
+snd-sis7019-objs := sis7019.o
snd-sonicvibes-objs := sonicvibes.o
snd-via82xx-objs := via82xx.o
snd-via82xx-modem-objs := via82xx_modem.o
@@ -48,6 +49,7 @@ obj-$(CONFIG_SND_MAESTRO3) += snd-maestr
obj-$(CONFIG_SND_MAESTRO3) += snd-maestro3.o
obj-$(CONFIG_SND_RME32) += snd-rme32.o
obj-$(CONFIG_SND_RME96) += snd-rme96.o
+obj-$(CONFIG_SND_SIS7019) += snd-sis7019.o
obj-$(CONFIG_SND_SONICVIBES) += snd-sonicvibes.o
obj-$(CONFIG_SND_VIA82XX) += snd-via82xx.o
obj-$(CONFIG_SND_VIA82XX_MODEM) += snd-via82xx-modem.o
diff -r 17223a4918b4 pci/sis7019.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sound/pci/sis7019.c Wed Nov 28 01:39:33 2007 -0500
@@ -0,0 +1,1466 @@
+/*
+ * Driver for SiS7019 Audio Accelerator
+ *
+ * Copyright (C) 2004-2007, David Dillow
+ * Written by David Dillow <dave thedillows org>
+ * Inspired by the Trident 4D-WaveDX/NX driver.
+ *
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <sound/driver.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/time.h>
+#include <linux/moduleparam.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <sound/core.h>
+#include <sound/ac97_codec.h>
+#include <sound/initval.h>
+#include "sis7019.h"
+
+MODULE_AUTHOR("David Dillow <dave thedillows org>");
+MODULE_DESCRIPTION("SiS 7019");
+MODULE_LICENSE("GPL");
+MODULE_SUPPORTED_DEVICE("{{SiS,SiS7019 Audio Accelerator}}");
+
+static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
+static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
+static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
+
+module_param_array(index, int, NULL, 0444);
+MODULE_PARM_DESC(index, "Index value for SiS7019 Audio Accelerator.");
+module_param_array(id, charp, NULL, 0444);
+MODULE_PARM_DESC(id, "ID string for SiS7019 Audio Accelerator.");
+module_param_array(enable, bool, NULL, 0444);
+MODULE_PARM_DESC(enable, "Enable SiS7019 Audio Accelerator.");
+
+static struct pci_device_id snd_sis7019_ids[] = {
+ { PCI_DEVICE(PCI_VENDOR_ID_SI, 0x7019) },
+ { 0, }
+};
+
+MODULE_DEVICE_TABLE(pci, snd_sis7019_ids);
+
+/* There are three timing modes for the voices.
+ *
+ * For both playback and capture, when the buffer is one or two periods long,
+ * we use the hardware's built-in Mid-Loop Interrupt and End-Loop Interrupt
+ * to let us know when the periods have ended.
+ *
+ * When performing playback with more than two periods per buffer, we set
+ * the "Stop Sample Offset" and tell the hardware to interrupt us when we
+ * reach it. We then update the offset and continue on until we are
+ * interrupted for the next period.
+ *
+ * Capture channels do not have a SSO, so we allocate a playback channel to
+ * use as a timer for the capture periods. We use the SSO on the playback
+ * channel to clock out virtual periods, and adjust the virtual period length
+ * to maintain synchronization. This algorithm came from the Trident driver.
+ *
+ * FIXME: It'd be nice to make use of some of the synth features in the
+ * hardware, but a woeful lack of documentation is a significant roadblock.
+ */
+struct voice {
+ u16 flags;
+#define VOICE_IN_USE 1
+#define VOICE_CAPTURE 2
+#define VOICE_SSO_TIMING 4
+#define VOICE_SYNC_TIMING 8
+ u16 sync_cso;
+ u16 period_size;
+ u16 buffer_size;
+ u16 sync_period_size;
+ u16 sync_buffer_size;
+ u32 sso;
+ u32 vperiod;
+ struct snd_pcm_substream *substream;
+ struct voice *timing;
+ void __iomem *ctrl_base;
+ void __iomem *wave_base;
+ void __iomem *sync_base;
+ int num;
+};
+
+/* We need four pages to store our wave parameters during a suspend. If
+ * we're not doing power management, we still need to allocate a page
+ * for the silence buffer.
+ */
+#ifdef CONFIG_PM
+#define SIS_SUSPEND_PAGES 4
+#else
+#define SIS_SUSPEND_PAGES 1
+#endif
+
+struct sis7019 {
+ unsigned long ioport;
+ void __iomem *ioaddr;
+ int irq;
+ int codecs_present;
+
+ struct pci_dev *pci;
+ struct snd_pcm *pcm;
+ struct snd_card *card;
+ struct snd_ac97 *ac97[3];
+
+ /* Protect against more than one thread hitting the AC97
+ * registers (in a more polite manner than pounding the hardware
+ * semaphore)
+ */
+ struct mutex ac97_mutex;
+
+ /* voice_lock protects allocation/freeing of the voice descriptions
+ */
+ spinlock_t voice_lock;
+
+ struct voice voices[64];
+ struct voice capture_voice;
+
+ /* Allocate pages to store the internal wave state during
+ * suspends. When we're operating, this can be used as a silence
+ * buffer for a timing channel.
+ */
+ void *suspend_state[SIS_SUSPEND_PAGES];
+
+ int silence_users;
+ dma_addr_t silence_dma_addr;
+};
+
+#define SIS_PRIMARY_CODEC_PRESENT 0x0001
+#define SIS_SECONDARY_CODEC_PRESENT 0x0002
+#define SIS_TERTIARY_CODEC_PRESENT 0x0004
+
+/* The HW has a limit in the loop end offset parameter of 0xfff8 samples,
+ * so our max buffer size is 0xfff8 samples * 2 channels * 2 bytes per sample.
+ * The minimum offset for LEO, SSO, and ESO is 9 samples, so that bounds our
+ * period. Given the two bounds, we get our maximum number of periods.
+ *
+ * We'll add a constraint upon open that limits the period and buffer sample
+ * size to values that are legal for the hardware.
+ */
+static struct snd_pcm_hardware sis_playback_hw_info = {
+ .info = (SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_BLOCK_TRANSFER |
+ SNDRV_PCM_INFO_SYNC_START |
+ SNDRV_PCM_INFO_RESUME),
+ .formats = (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 |
+ SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE),
+ .rates = SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_CONTINUOUS,
+ .rate_min = 4000,
+ .rate_max = 48000,
+ .channels_min = 1,
+ .channels_max = 2,
+ .buffer_bytes_max = (0xfff8 * 4),
+ .period_bytes_min = 9,
+ .period_bytes_max = (0xfff8 * 4),
+ .periods_min = 1,
+ .periods_max = (0xfff8 / 9),
+};
+
+static struct snd_pcm_hardware sis_capture_hw_info = {
+ .info = (SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_BLOCK_TRANSFER |
+ SNDRV_PCM_INFO_SYNC_START |
+ SNDRV_PCM_INFO_RESUME),
+ .formats = (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 |
+ SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE),
+ .rates = SNDRV_PCM_RATE_48000,
+ .rate_min = 4000,
+ .rate_max = 48000,
+ .channels_min = 1,
+ .channels_max = 2,
+ .buffer_bytes_max = (0xfff7 * 4),
+ .period_bytes_min = 9,
+ .period_bytes_max = (0xfff7 * 4),
+ .periods_min = 1,
+ .periods_max = (0xfff8 / 9),
+};
+
+static void sis_update_sso(struct voice *voice, u16 period)
+{
+ void __iomem *base = voice->ctrl_base;
+
+ voice->sso += period;
+ if (voice->sso >= voice->buffer_size)
+ voice->sso -= voice->buffer_size;
+
+ /* Enforce the hardware limit */
+ if (voice->sso < 8)
+ voice->sso = 8;
+
+ /* The SSO is in the upper 16 bits of the register. */
+ writew(voice->sso & 0xffff, base + SIS_PLAY_DMA_SSO_ESO + 2);
+}
+
+static void sis_update_voice(struct voice *voice)
+{
+ if (voice->flags & VOICE_SSO_TIMING) {
+ sis_update_sso(voice, voice->period_size);
+ } else if (voice->flags & VOICE_SYNC_TIMING) {
+ int sync;
+
+ /* If we've not hit the end of the virtual period, update
+ * our records and keep going.
+ */
+ if (voice->vperiod > voice->period_size) {
+ voice->vperiod -= voice->period_size;
+ if (voice->vperiod < voice->period_size)
+ sis_update_sso(voice, voice->vperiod);
+ else
+ sis_update_sso(voice, voice->period_size);
+ return;
+ }
+
+ /* Calculate our relative offset between the target and
+ * the actual CSO value. Since we're operating in a loop,
+ * if the value is more than half way around, we can
+ * consider ourselves wrapped.
+ */
+ sync = voice->sync_cso;
+ sync -= readw(voice->sync_base + SIS_CAPTURE_DMA_FORMAT_CSO);
+ if (sync > (voice->sync_buffer_size / 2))
+ sync -= voice->sync_buffer_size;
+
+ /* If sync is positive, then we interrupted too early, and
+ * we'll need to come back in a few samples and try again.
+ * There's a minimum wait, as it takes some time for the DMA
+ * engine to startup, etc...
+ */
+ if (sync > 0) {
+ if (sync < 16)
+ sync = 16;
+ sis_update_sso(voice, sync);
+ return;
+ }
+
+ /* Ok, we interrupted right on time, or (hopefully) just
+ * a bit late. We'll adjst our next waiting period based
+ * on how close we got.
+ *
+ * We need to stay just behind the actual channel to ensure
+ * it really is past a period when we get our interrupt --
+ * otherwise we'll fall into the early code above and have
+ * a minimum wait time, which makes us quite late here,
+ * eating into the user's time to refresh the buffer, esp.
+ * if using small periods.
+ *
+ * If we're less than 9 samples behind, we're on target.
+ */
+ if (sync > -9)
+ voice->vperiod = voice->sync_period_size + 1;
+ else
+ voice->vperiod = voice->sync_period_size - 4;
+
+ if (voice->vperiod < voice->buffer_size) {
+ sis_update_sso(voice, voice->vperiod);
+ voice->vperiod = 0;
+ } else
+ sis_update_sso(voice, voice->period_size);
+
+ sync = voice->sync_cso + voice->sync_period_size;
+ if (sync >= voice->sync_buffer_size)
+ sync -= voice->sync_buffer_size;
+ voice->sync_cso = sync;
+ }
+
+ snd_pcm_period_elapsed(voice->substream);
+}
+
+static void sis_voice_irq(u32 status, struct voice *voice)
+{
+ int bit;
+
+ while (status) {
+ bit = __ffs(status);
+ status >>= bit + 1;
+ voice += bit;
+ sis_update_voice(voice);
+ voice++;
+ }
+}
+
+static irqreturn_t sis_interrupt(int irq, void *dev)
+{
+ struct sis7019 *sis = dev;
+ unsigned long io = sis->ioport;
+ struct voice *voice;
+ u32 intr, status;
+
+ /* We only use the DMA interrupts, and we don't enable any other
+ * source of interrupts. But, it is possible to see an interupt
+ * status that didn't actually interrupt us, so eliminate anything
+ * we're not expecting to avoid falsely claiming an IRQ, and an
+ * ensuing endless loop.
+ */
+ intr = inl(io + SIS_GISR);
+ intr &= SIS_GISR_AUDIO_PLAY_DMA_IRQ_STATUS |
+ SIS_GISR_AUDIO_RECORD_DMA_IRQ_STATUS;
+ if (!intr)
+ return IRQ_NONE;
+
+ do {
+ status = inl(io + SIS_PISR_A);
+ if (status) {
+ sis_voice_irq(status, sis->voices);
+ outl(status, io + SIS_PISR_A);
+ }
+
+ status = inl(io + SIS_PISR_B);
+ if (status) {
+ sis_voice_irq(status, &sis->voices[32]);
+ outl(status, io + SIS_PISR_B);
+ }
+
+ status = inl(io + SIS_RISR);
+ if (status) {
+ voice = &sis->capture_voice;
+ if (!voice->timing)
+ snd_pcm_period_elapsed(voice->substream);
+
+ outl(status, io + SIS_RISR);
+ }
+
+ outl(intr, io + SIS_GISR);
+ intr = inl(io + SIS_GISR);
+ intr &= SIS_GISR_AUDIO_PLAY_DMA_IRQ_STATUS |
+ SIS_GISR_AUDIO_RECORD_DMA_IRQ_STATUS;
+ } while (intr);
+
+ return IRQ_HANDLED;
+}
+
+static u32 sis_rate_to_delta(unsigned int rate)
+{
+ u32 delta;
+
+ /* This was copied from the trident driver, but it seems its gotten
+ * around a bit... nevertheless, it works well.
+ *
+ * We special case 44100 and 8000 since rounding with the equation
+ * does not give us an accurate enough value. For 11025 and 22050
+ * the equation gives us the best answer. All other frequencies will
+ * also use the equation. JDW
+ */
+ if (rate == 44100)
+ delta = 0xeb3;
+ else if (rate == 8000)
+ delta = 0x2ab;
+ else if (rate == 48000)
+ delta = 0x1000;
+ else
+ delta = (((rate << 12) + 24000) / 48000) & 0x0000ffff;
+ return delta;
+}
+
+static void __sis_map_silence(struct sis7019 *sis)
+{
+ /* Must hold the voice_lock on entry */
+ if (!sis->silence_users)
+ sis->silence_dma_addr = pci_map_single(sis->pci,
+ sis->suspend_state[0],
+ 4096, PCI_DMA_TODEVICE);
+ sis->silence_users++;
+}
+
+static void __sis_unmap_silence(struct sis7019 *sis)
+{
+ /* Must hold the voice_lock on entry */
+ sis->silence_users--;
+ if (!sis->silence_users)
+ pci_unmap_single(sis->pci, sis->silence_dma_addr, 4096,
+ PCI_DMA_TODEVICE);
+}
+
+static void sis_free_voice(struct sis7019 *sis, struct voice *voice)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&sis->voice_lock, flags);
+ if (voice->timing) {
+ __sis_unmap_silence(sis);
+ voice->timing->flags = ~(VOICE_IN_USE | VOICE_SSO_TIMING |
+ VOICE_SYNC_TIMING);
+ voice->timing = NULL;
+ }
+ voice->flags &= ~(VOICE_IN_USE | VOICE_SSO_TIMING | VOICE_SYNC_TIMING);
+ spin_unlock_irqrestore(&sis->voice_lock, flags);
+}
+
+static struct voice *__sis_alloc_playback_voice(struct sis7019 *sis)
+{
+ /* Must hold the voice_lock on entry */
+ struct voice *voice;
+ int i;
+
+ for (i = 0; i < 64; i++) {
+ voice = &sis->voices[i];
+ if (voice->flags & VOICE_IN_USE)
+ continue;
+ voice->flags |= VOICE_IN_USE;
+ goto found_one;
+ }
+ voice = NULL;
+
+found_one:
+ return voice;
+}
+
+static struct voice *sis_alloc_playback_voice(struct sis7019 *sis)
+{
+ struct voice *voice;
+ unsigned long flags;
+
+ spin_lock_irqsave(&sis->voice_lock, flags);
+ voice = __sis_alloc_playback_voice(sis);
+ spin_unlock_irqrestore(&sis->voice_lock, flags);
+
+ return voice;
+}
+
+static int sis_alloc_timing_voice(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *hw_params)
+{
+ struct sis7019 *sis = snd_pcm_substream_chip(substream);
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct voice *voice = runtime->private_data;
+ unsigned int period_size, buffer_size;
+ unsigned long flags;
+ int needed;
+
+ /* If there are one or two periods per buffer, we don't need a
+ * timing voice, as we can use the capture channel's interrupts
+ * to clock out the periods.
+ */
+ period_size = params_period_size(hw_params);
+ buffer_size = params_buffer_size(hw_params);
+ needed = (period_size != buffer_size &&
+ period_size != (buffer_size / 2));
+
+ if (needed && !voice->timing) {
+ spin_lock_irqsave(&sis->voice_lock, flags);
+ voice->timing = __sis_alloc_playback_voice(sis);
+ if (voice->timing)
+ __sis_map_silence(sis);
+ spin_unlock_irqrestore(&sis->voice_lock, flags);
+ if (!voice->timing)
+ return -ENOMEM;
+ voice->timing->substream = substream;
+ } else if (!needed && voice->timing) {
+ sis_free_voice(sis, voice);
+ voice->timing = NULL;
+ }
+
+ return 0;
+}
+
+static int sis_playback_open(struct snd_pcm_substream *substream)
+{
+ struct sis7019 *sis = snd_pcm_substream_chip(substream);
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct voice *voice;
+
+ voice = sis_alloc_playback_voice(sis);
+ if (!voice)
+ return -EAGAIN;
+
+ voice->substream = substream;
+ runtime->private_data = voice;
+ runtime->hw = sis_playback_hw_info;
+ snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
+ 9, 0xfff8);
+ snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
+ 9, 0xfff8);
+ snd_pcm_set_sync(substream);
+ return 0;
+}
+
+static int sis_substream_close(struct snd_pcm_substream *substream)
+{
+ struct sis7019 *sis = snd_pcm_substream_chip(substream);
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct voice *voice = runtime->private_data;
+
+ sis_free_voice(sis, voice);
+ return 0;
+}
+
+static int sis_playback_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *hw_params)
+{
+ return snd_pcm_lib_malloc_pages(substream,
+ params_buffer_bytes(hw_params));
+}
+
+static int sis_hw_free(struct snd_pcm_substream *substream)
+{
+ return snd_pcm_lib_free_pages(substream);
+}
+
+static int sis_pcm_playback_prepare(struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct voice *voice = runtime->private_data;
+ void __iomem *ctrl_base = voice->ctrl_base;
+ void __iomem *wave_base = voice->wave_base;
+ u32 format, dma_addr, control, sso_eso, delta, reg;
+ u16 leo;
+
+ /* We rely on the PCM core to ensure that the parameters for this
+ * substream do not change on us while we're programming the HW.
+ */
+ format = 0;
+ if (snd_pcm_format_width(runtime->format) == 8)
+ format |= SIS_PLAY_DMA_FORMAT_8BIT;
+ if (!snd_pcm_format_signed(runtime->format))
+ format |= SIS_PLAY_DMA_FORMAT_UNSIGNED;
+ if (runtime->channels == 1)
+ format |= SIS_PLAY_DMA_FORMAT_MONO;
+
+ /* The baseline setup is for a single period per buffer, and
+ * we add bells and whistles as needed from there.
+ */
+ dma_addr = runtime->dma_addr;
+ leo = runtime->buffer_size - 1;
+ control = leo | SIS_PLAY_DMA_LOOP | SIS_PLAY_DMA_INTR_AT_LEO;
+ sso_eso = leo;
+
+ if (runtime->period_size == (runtime->buffer_size / 2)) {
+ control |= SIS_PLAY_DMA_INTR_AT_MLP;
+ } else if (runtime->period_size != runtime->buffer_size) {
+ voice->flags |= VOICE_SSO_TIMING;
+ voice->sso = runtime->period_size - 1;
+ voice->period_size = runtime->period_size;
+ voice->buffer_size = runtime->buffer_size;
+
+ control &= ~SIS_PLAY_DMA_INTR_AT_LEO;
+ control |= SIS_PLAY_DMA_INTR_AT_SSO;
+ sso_eso |= (runtime->period_size - 1) << 16;
+ }
+
+ delta = sis_rate_to_delta(runtime->rate);
+
+ /* Ok, we're ready to go, set up the channel.
+ */
+ writel(format, ctrl_base + SIS_PLAY_DMA_FORMAT_CSO);
+ writel(dma_addr, ctrl_base + SIS_PLAY_DMA_BASE);
+ writel(control, ctrl_base + SIS_PLAY_DMA_CONTROL);
+ writel(sso_eso, ctrl_base + SIS_PLAY_DMA_SSO_ESO);
+
+ for (reg = 0; reg < SIS_WAVE_SIZE; reg += 4)
+ writel(0, wave_base + reg);
+
+ writel(SIS_WAVE_GENERAL_WAVE_VOLUME, wave_base + SIS_WAVE_GENERAL);
+ writel(delta << 16, wave_base + SIS_WAVE_GENERAL_ARTICULATION);
+ writel(SIS_WAVE_CHANNEL_CONTROL_FIRST_SAMPLE |
+ SIS_WAVE_CHANNEL_CONTROL_AMP_ENABLE |
+ SIS_WAVE_CHANNEL_CONTROL_INTERPOLATE_ENABLE,
+ wave_base + SIS_WAVE_CHANNEL_CONTROL);
+
+ /* Force PCI writes to post. */
+ readl(ctrl_base);
+
+ return 0;
+}
+
+static int sis_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
+{
+ struct sis7019 *sis = snd_pcm_substream_chip(substream);
+ unsigned long io = sis->ioport;
+ struct snd_pcm_substream *s;
+ struct voice *voice;
+ void *chip;
+ int starting;
+ u32 record = 0;
+ u32 play[2] = { 0, 0 };
+
+ /* No locks needed, as the PCM core will hold the locks on the
+ * substreams, and the HW will only start/stop the indicated voices
+ * without changing the state of the others.
+ */
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ starting = 1;
+ break;
+ case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ starting = 0;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ snd_pcm_group_for_each_entry(s, substream) {
+ /* Make sure it is for us... */
+ chip = snd_pcm_substream_chip(s);
+ if (chip != sis)
+ continue;
+
+ voice = s->runtime->private_data;
+ if (voice->flags & VOICE_CAPTURE) {
+ record |= 1 << voice->num;
+ voice = voice->timing;
+ }
+
+ /* voice could be NULL if this a recording stream, and it
+ * doesn't have an external timing channel.
+ */
+ if (voice)
+ play[voice->num / 32] |= 1 << (voice->num & 0x1f);
+
+ snd_pcm_trigger_done(s, substream);
+ }
+
+ if (starting) {
+ if (record)
+ outl(record, io + SIS_RECORD_START_REG);
+ if (play[0])
+ outl(play[0], io + SIS_PLAY_START_A_REG);
+ if (play[1])
+ outl(play[1], io + SIS_PLAY_START_B_REG);
+ } else {
+ if (record)
+ outl(record, io + SIS_RECORD_STOP_REG);
+ if (play[0])
+ outl(play[0], io + SIS_PLAY_STOP_A_REG);
+ if (play[1])
+ outl(play[1], io + SIS_PLAY_STOP_B_REG);
+ }
+ return 0;
+}
+
+static snd_pcm_uframes_t sis_pcm_pointer(struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct voice *voice = runtime->private_data;
+ u32 cso;
+
+ cso = readl(voice->ctrl_base + SIS_PLAY_DMA_FORMAT_CSO);
+ cso &= 0xffff;
+ return cso;
+}
+
+static int sis_capture_open(struct snd_pcm_substream *substream)
+{
+ struct sis7019 *sis = snd_pcm_substream_chip(substream);
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct voice *voice = &sis->capture_voice;
+ unsigned long flags;
+
+ /* FIXME: The driver only supports recording from one channel
+ * at the moment, but it could support more.
+ */
+ spin_lock_irqsave(&sis->voice_lock, flags);
+ if (voice->flags & VOICE_IN_USE)
+ voice = NULL;
+ else
+ voice->flags |= VOICE_IN_USE;
+ spin_unlock_irqrestore(&sis->voice_lock, flags);
+
+ if (!voice)
+ return -EAGAIN;
+
+ voice->substream = substream;
+ runtime->private_data = voice;
+ runtime->hw = sis_capture_hw_info;
+ runtime->hw.rates = sis->ac97[0]->rates[AC97_RATES_ADC];
+ snd_pcm_limit_hw_rates(runtime);
+ snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_SIZE,
+ 9, 0xfff8);
+ snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
+ 9, 0xfff8);
+ snd_pcm_set_sync(substream);
+ return 0;
+}
+
+static int sis_capture_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *hw_params)
+{
+ struct sis7019 *sis = snd_pcm_substream_chip(substream);
+ int rc;
+
+ rc = snd_ac97_set_rate(sis->ac97[0], AC97_PCM_LR_ADC_RATE,
+ params_rate(hw_params));
+ if (rc)
+ goto out;
+
+ rc = snd_pcm_lib_malloc_pages(substream,
+ params_buffer_bytes(hw_params));
+ if (rc < 0)
+ goto out;
+
+ rc = sis_alloc_timing_voice(substream, hw_params);
+
+out:
+ return rc;
+}
+
+static void sis_prepare_timing_voice(struct voice *timing, struct voice *cap,
+ struct snd_pcm_runtime *runtime)
+{
+ u16 buffer_size, period_size;
+ u32 vperiod, sso;
+
+ timing->flags |= VOICE_SYNC_TIMING;
+ timing->sync_base = cap->ctrl_base;
+ timing->sync_cso = runtime->period_size - 1;
+ timing->sync_period_size = runtime->period_size;
+ timing->sync_buffer_size = runtime->buffer_size;
+
+ /* Set our initial buffer and period as large as we can given a
+ * single page of silence.
+ */
+ buffer_size = 4096 / runtime->channels;
+ buffer_size /= snd_pcm_format_size(runtime->format, 1);
+ period_size = buffer_size;
+
+ /* Initially, we want to interrupt just a bit behind the end of
+ * the period we're clocking out. 10 samples seems to give a good
+ * delay.
+ *
+ * We want to spread our interrupts throughout the virtual period,
+ * so that we don't end up with two interrupts back to back at the
+ * end -- this helps minimize the effects of any jitter. Adjust our
+ * clocking period size so that the last period is at least a fourth
+ * of a full period.
+ *
+ * This is all moot if we don't need to use virtual periods.
+ */
+ vperiod = runtime->period_size + 10;
+ if (vperiod > period_size) {
+ u16 tail = vperiod % period_size;
+ u16 quarter_period = period_size / 4;
+
+ if (tail && tail < quarter_period) {
+ u16 loops = vperiod / period_size;
+
+ tail = quarter_period - tail;
+ tail += loops - 1;
+ tail /= loops;
+ period_size -= tail;
+ }
+
+ sso = period_size - 1;
+ } else {
+ /* The initial period will fit inside the buffer, so we
+ * don't need to use virtual periods -- disable them.
+ */
+ period_size = runtime->period_size;
+ sso = vperiod - 1;
+ vperiod = 0;
+ }
+
+ timing->period_size = period_size;
+ timing->buffer_size = buffer_size;
+ timing->sso = sso;
+ timing->vperiod = vperiod;
+}
+
+static int sis_pcm_capture_prepare(struct snd_pcm_substream *substream)
+{
+ struct sis7019 *sis = snd_pcm_substream_chip(substream);
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct voice *voice = runtime->private_data;
+ struct voice *timing = voice->timing;
+ void __iomem *rec_base = voice->ctrl_base;
+ void __iomem *play_base = NULL;
+ void __iomem *wave_base = NULL;
+ u32 format, dma_addr, rec_ctrl;
+ u16 leo;
+
+ /* The following variables are only used if there is a timing channel.
+ */
+ u32 uninitialized_var(timing_ctrl);
+ u32 uninitialized_var(sso_eso);
+ u32 uninitialized_var(delta);
+
+ /* We rely on the PCM core to ensure that the parameters for this
+ * substream do not change on us while we're programming the HW.
+ */
+ format = 0;
+ if (snd_pcm_format_width(runtime->format) == 8)
+ format = SIS_CAPTURE_DMA_FORMAT_8BIT;
+ if (!snd_pcm_format_signed(runtime->format))
+ format |= SIS_CAPTURE_DMA_FORMAT_UNSIGNED;
+ if (runtime->channels == 1)
+ format |= SIS_CAPTURE_DMA_FORMAT_MONO;
+
+ dma_addr = runtime->dma_addr;
+ leo = runtime->buffer_size - 1;
+ rec_ctrl = leo | SIS_CAPTURE_DMA_LOOP;
+ if (timing) {
+ /* We're using a timing voice, so the capture voice will
+ * not need to generate interrupts.
+ */
+ sis_prepare_timing_voice(timing, voice, runtime);
+
+ timing_ctrl = timing->buffer_size - 1;
+ timing_ctrl |= SIS_PLAY_DMA_LOOP | SIS_PLAY_DMA_INTR_AT_SSO;
+ sso_eso = timing->buffer_size - 1;;
+ sso_eso |= timing->sso << 16;
+
+ delta = sis_rate_to_delta(runtime->rate);
+
+ play_base = timing->ctrl_base;
+ wave_base = timing->wave_base;
+ } else {
+ /* We've just got one or two periods, so we can use the
+ * capture voice's interrupt generation.
+ */
+ rec_ctrl |= SIS_CAPTURE_DMA_INTR_AT_LEO;
+ if (runtime->period_size != runtime->buffer_size)
+ rec_ctrl |= SIS_CAPTURE_DMA_INTR_AT_MLP;
+ }
+
+ /* We're ready to program the channel(s)
+ */
+ writel(format, rec_base + SIS_CAPTURE_DMA_FORMAT_CSO);
+ writel(dma_addr, rec_base + SIS_CAPTURE_DMA_BASE);
+ writel(rec_ctrl, rec_base + SIS_CAPTURE_DMA_CONTROL);
+
+ if (play_base) {
+ u32 reg;
+
+ writel(format, play_base + SIS_PLAY_DMA_FORMAT_CSO);
+ writel(sis->silence_dma_addr, play_base + SIS_PLAY_DMA_BASE);
+ writel(timing_ctrl, play_base + SIS_PLAY_DMA_CONTROL);
+ writel(sso_eso, play_base + SIS_PLAY_DMA_SSO_ESO);
+
+ for (reg = 0; reg < SIS_WAVE_SIZE; reg += 4)
+ writel(0, wave_base + reg);
+
+ writel(SIS_WAVE_GENERAL_WAVE_VOLUME,
+ wave_base + SIS_WAVE_GENERAL);
+ writel(delta << 16, wave_base + SIS_WAVE_GENERAL_ARTICULATION);
+ writel(SIS_WAVE_CHANNEL_CONTROL_FIRST_SAMPLE |
+ SIS_WAVE_CHANNEL_CONTROL_AMP_ENABLE |
+ SIS_WAVE_CHANNEL_CONTROL_INTERPOLATE_ENABLE,
+ wave_base + SIS_WAVE_CHANNEL_CONTROL);
+ }
+
+ /* Force the writes to post. */
+ readl(rec_base);
+
+ return 0;
+}
+
+static struct snd_pcm_ops sis_playback_ops = {
+ .open = sis_playback_open,
+ .close = sis_substream_close,
+ .ioctl = snd_pcm_lib_ioctl,
+ .hw_params = sis_playback_hw_params,
+ .hw_free = sis_hw_free,
+ .prepare = sis_pcm_playback_prepare,
+ .trigger = sis_pcm_trigger,
+ .pointer = sis_pcm_pointer,
+};
+
+static struct snd_pcm_ops sis_capture_ops = {
+ .open = sis_capture_open,
+ .close = sis_substream_close,
+ .ioctl = snd_pcm_lib_ioctl,
+ .hw_params = sis_capture_hw_params,
+ .hw_free = sis_hw_free,
+ .prepare = sis_pcm_capture_prepare,
+ .trigger = sis_pcm_trigger,
+ .pointer = sis_pcm_pointer,
+};
+
+static int __devinit sis_pcm_create(struct sis7019 *sis)
+{
+ struct snd_pcm *pcm;
+ int rc;
+
+ rc = snd_pcm_new(sis->card, "SiS 7019", 0, 40, 1, &pcm);
+ if (rc)
+ return rc;
+
+ pcm->private_data = sis;
+ strcpy(pcm->name, "SiS 7019");
+ sis->pcm = pcm;
+
+ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &sis_playback_ops);
+ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &sis_capture_ops);
+
+ /* Try to preallocate some memory, but it's not the end of the
+ * world if this fails.
+ */
+ snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
+ snd_dma_pci_data(sis->pci), 64*1024, 128*1024);
+
+ return 0;
+}
+
+static unsigned short sis_ac97_rw(struct sis7019 *sis, int codec, u32 cmd)
+{
+ unsigned long io = sis->ioport;
+ unsigned short val = 0xffff;
+ u16 status;
+ u16 rdy;
+ int count;
+ const static u16 codec_ready[3] = {
+ SIS_AC97_STATUS_CODEC_READY,
+ SIS_AC97_STATUS_CODEC2_READY,
+ SIS_AC97_STATUS_CODEC3_READY,
+ };
+
+ rdy = codec_ready[codec];
+
+
+ /* Get the AC97 semaphore -- software first, so we don't spin
+ * pounding out IO reads on the hardware semaphore...
+ */
+ mutex_lock(&sis->ac97_mutex);
+
+ count = 0xffff;
+ while ((inw(io + SIS_AC97_SEMA) & SIS_AC97_SEMA_BUSY) && --count)
+ udelay(1);
+
+ if (!count)
+ goto timeout;
+
+ /* ... and wait for any outstanding commands to complete ...
+ */
+ count = 0xffff;
+ do {
+ status = inw(io + SIS_AC97_STATUS);
+ if ((status & rdy) && !(status & SIS_AC97_STATUS_BUSY))
+ break;
+
+ udelay(1);
+ } while (--count);
+
+ if (!count)
+ goto timeout_sema;
+
+ /* ... before sending our command and waiting for it to finish ...
+ */
+ outl(cmd, io + SIS_AC97_CMD);
+ udelay(10);
+
+ count = 0xffff;
+ while ((inw(io + SIS_AC97_STATUS) & SIS_AC97_STATUS_BUSY) && --count)
+ udelay(1);
+
+ /* ... and reading the results (if any).
+ */
+ val = inl(io + SIS_AC97_CMD) >> 16;
+
+timeout_sema:
+ outl(SIS_AC97_SEMA_RELEASE, io + SIS_AC97_SEMA);
+timeout:
+ mutex_unlock(&sis->ac97_mutex);
+
+ if (!count) {
+ printk(KERN_ERR "sis7019: ac97 codec %d timeout cmd 0x%08x\n",
+ codec, cmd);
+ }
+
+ return val;
+}
+
+static void sis_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
+ unsigned short val)
+{
+ const static u32 cmd[3] = {
+ SIS_AC97_CMD_CODEC_WRITE,
+ SIS_AC97_CMD_CODEC2_WRITE,
+ SIS_AC97_CMD_CODEC3_WRITE,
+ };
+ sis_ac97_rw(ac97->private_data, ac97->num,
+ (val << 16) | (reg << 8) | cmd[ac97->num]);
+}
+
+static unsigned short sis_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
+{
+ const static u32 cmd[3] = {
+ SIS_AC97_CMD_CODEC_READ,
+ SIS_AC97_CMD_CODEC2_READ,
+ SIS_AC97_CMD_CODEC3_READ,
+ };
+ return sis_ac97_rw(ac97->private_data, ac97->num,
+ (reg << 8) | cmd[ac97->num]);
+}
+
+static int __devinit sis_mixer_create(struct sis7019 *sis)
+{
+ struct snd_ac97_bus *bus;
+ struct snd_ac97_template ac97;
+ static struct snd_ac97_bus_ops ops = {
+ .write = sis_ac97_write,
+ .read = sis_ac97_read,
+ };
+ int rc;
+
+ memset(&ac97, 0, sizeof(ac97));
+ ac97.private_data = sis;
+
+ rc = snd_ac97_bus(sis->card, 0, &ops, NULL, &bus);
+ if (!rc && sis->codecs_present & SIS_PRIMARY_CODEC_PRESENT)
+ rc = snd_ac97_mixer(bus, &ac97, &sis->ac97[0]);
+ ac97.num = 1;
+ if (!rc && (sis->codecs_present & SIS_SECONDARY_CODEC_PRESENT))
+ rc = snd_ac97_mixer(bus, &ac97, &sis->ac97[1]);
+ ac97.num = 2;
+ if (!rc && (sis->codecs_present & SIS_TERTIARY_CODEC_PRESENT))
+ rc = snd_ac97_mixer(bus, &ac97, &sis->ac97[2]);
+
+ /* If we return an error here, then snd_card_free() should
+ * free up any ac97 codecs that got created, as well as the bus.
+ */
+ return rc;
+}
+
+static void sis_free_suspend(struct sis7019 *sis)
+{
+ int i;
+
+ for (i = 0; i < SIS_SUSPEND_PAGES; i++)
+ kfree(sis->suspend_state[i]);
+}
+
+static int sis_chip_free(struct sis7019 *sis)
+{
+ /* Reset the chip, and disable all interrputs.
+ */
+ outl(SIS_GCR_SOFTWARE_RESET, sis->ioport + SIS_GCR);
+ udelay(10);
+ outl(0, sis->ioport + SIS_GCR);
+ outl(0, sis->ioport + SIS_GIER);
+
+ /* Now, free everything we allocated.
+ */
+ if (sis->irq >= 0)
+ free_irq(sis->irq, sis);
+
+ if (sis->ioaddr)
+ iounmap(sis->ioaddr);
+
+ pci_release_regions(sis->pci);
+ pci_disable_device(sis->pci);
+
+ sis_free_suspend(sis);
+ return 0;
+}
+
+static int sis_dev_free(struct snd_device *dev)
+{
+ struct sis7019 *sis = dev->device_data;
+ return sis_chip_free(sis);
+}
+
+static int sis_chip_init(struct sis7019 *sis)
+{
+ unsigned long io = sis->ioport;
+ void __iomem *ioaddr = sis->ioaddr;
+ u16 status;
+ int count;
+ int i;
+
+ /* Reset the audio controller
+ */
+ outl(SIS_GCR_SOFTWARE_RESET, io + SIS_GCR);
+ udelay(10);
+ outl(0, io + SIS_GCR);
+
+ /* Get the AC-link semaphore, and reset the codecs
+ */
+ count = 0xffff;
+ while ((inw(io + SIS_AC97_SEMA) & SIS_AC97_SEMA_BUSY) && --count)
+ udelay(1);
+
+ if (!count)
+ return -EIO;
+
+ outl(SIS_AC97_CMD_CODEC_COLD_RESET, io + SIS_AC97_CMD);
+ udelay(10);
+
+ count = 0xffff;
+ while ((inw(io + SIS_AC97_STATUS) & SIS_AC97_STATUS_BUSY) && --count)
+ udelay(1);
+
+ /* Now that we've finished the reset, find out what's attached.
+ */
+ status = inl(io + SIS_AC97_STATUS);
+ if (status & SIS_AC97_STATUS_CODEC_READY)
+ sis->codecs_present |= SIS_PRIMARY_CODEC_PRESENT;
+ if (status & SIS_AC97_STATUS_CODEC2_READY)
+ sis->codecs_present |= SIS_SECONDARY_CODEC_PRESENT;
+ if (status & SIS_AC97_STATUS_CODEC3_READY)
+ sis->codecs_present |= SIS_TERTIARY_CODEC_PRESENT;
+
+ /* All done, let go of the semaphore, and check for errors
+ */
+ outl(SIS_AC97_SEMA_RELEASE, io + SIS_AC97_SEMA);
+ if (!sis->codecs_present || !count)
+ return -EIO;
+
+ /* Let the hardware know that the audio driver is alive,
+ * and enable PCM slots on the AC-link for L/R playback (3 & 4) and
+ * record channels. We're going to want to use Variable Rate Audio
+ * for recording, to avoid needlessly resampling from 48kHZ.
+ */
+ outl(SIS_AC97_CONF_AUDIO_ALIVE, io + SIS_AC97_CONF);
+ outl(SIS_AC97_CONF_AUDIO_ALIVE | SIS_AC97_CONF_PCM_LR_ENABLE |
+ SIS_AC97_CONF_PCM_CAP_MIC_ENABLE |
+ SIS_AC97_CONF_PCM_CAP_LR_ENABLE |
+ SIS_AC97_CONF_CODEC_VRA_ENABLE, io + SIS_AC97_CONF);
+
+ /* All AC97 PCM slots should be sourced from sub-mixer 0.
+ */
+ outl(0, io + SIS_AC97_PSR);
+
+ /* There is only one valid DMA setup for a PCI environment.
+ */
+ outl(SIS_DMA_CSR_PCI_SETTINGS, io + SIS_DMA_CSR);
+
+ /* Reset the syncronization groups for all of the channels
+ * to be asyncronous. If we start doing SPDIF or 5.1 sound, etc.
+ * we'll need to change how we handle these. Until then, we just
+ * assign sub-mixer 0 to all playback channels, and avoid any
+ * attenuation on the audio.
+ */
+ outl(0, io + SIS_PLAY_SYNC_GROUP_A);
+ outl(0, io + SIS_PLAY_SYNC_GROUP_B);
+ outl(0, io + SIS_PLAY_SYNC_GROUP_C);
+ outl(0, io + SIS_PLAY_SYNC_GROUP_D);
+ outl(0, io + SIS_MIXER_SYNC_GROUP);
+
+ for (i = 0; i < 64; i++) {
+ writel(i, SIS_MIXER_START_ADDR(ioaddr, i));
+ writel(SIS_MIXER_RIGHT_NO_ATTEN | SIS_MIXER_LEFT_NO_ATTEN |
+ SIS_MIXER_DEST_0, SIS_MIXER_ADDR(ioaddr, i));
+ }
+
+ /* Don't attenuate any audio set for the wave amplifier.
+ *
+ * FIXME: Maximum attenuation is set for the music amp, which will
+ * need to change if we start using the synth engine.
+ */
+ outl(0xffff0000, io + SIS_WEVCR);
+
+ /* Ensure that the wave engine is in normal operating mode.
+ */
+ outl(0, io + SIS_WECCR);
+
+ /* Go ahead and enable the DMA interrupts. They won't go live
+ * until we start a channel.
+ */
+ outl(SIS_GIER_AUDIO_PLAY_DMA_IRQ_ENABLE |
+ SIS_GIER_AUDIO_RECORD_DMA_IRQ_ENABLE, io + SIS_GIER);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int sis_suspend(struct pci_dev *pci, pm_message_t state)
+{
+ struct snd_card *card = pci_get_drvdata(pci);
+ struct sis7019 *sis = card->private_data;
+ void __iomem *ioaddr = sis->ioaddr;
+ int i;
+
+ snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
+ snd_pcm_suspend_all(sis->pcm);
+ if (sis->codecs_present & SIS_PRIMARY_CODEC_PRESENT)
+ snd_ac97_suspend(sis->ac97[0]);
+ if (sis->codecs_present & SIS_SECONDARY_CODEC_PRESENT)
+ snd_ac97_suspend(sis->ac97[1]);
+ if (sis->codecs_present & SIS_TERTIARY_CODEC_PRESENT)
+ snd_ac97_suspend(sis->ac97[2]);
+
+ /* snd_pcm_suspend_all() stopped all channels, so we're quiescent.
+ */
+ if (sis->irq >= 0) {
+ synchronize_irq(sis->irq);
+ free_irq(sis->irq, sis);
+ sis->irq = -1;
+ }
+
+ /* Save the internal state away
+ */
+ for (i = 0; i < 4; i++ ) {
+ memcpy_fromio(sis->suspend_state[i], ioaddr, 4096);
+ ioaddr += 4096;
+ }
+
+ pci_disable_device(pci);
+ pci_save_state(pci);
+ pci_set_power_state(pci, pci_choose_state(pci, state));
+ return 0;
+}
+
+static int sis_resume(struct pci_dev *pci)
+{
+ struct snd_card *card = pci_get_drvdata(pci);
+ struct sis7019 *sis = card->private_data;
+ void __iomem *ioaddr = sis->ioaddr;
+ int i;
+
+ pci_set_power_state(pci, PCI_D0);
+ pci_restore_state(pci);
+
+ if (pci_enable_device(pci) < 0) {
+ printk(KERN_ERR "sis7019: unable to re-enable device\n");
+ goto error;
+ }
+
+ if (sis_chip_init(sis)) {
+ printk(KERN_ERR "sis7019: unable to re-init controller\n");
+ goto error;
+ }
+
+ if (request_irq(pci->irq, sis_interrupt, IRQF_DISABLED|IRQF_SHARED,
+ card->shortname, sis)) {
+ printk(KERN_ERR "sis7019: unable to regain IRQ %d\n", pci->irq);
+ goto error;
+ }
+
+ /* Restore saved state, then clear out the page we use for the
+ * silence buffer.
+ */
+ for (i = 0; i < 4; i++ ) {
+ memcpy_toio(ioaddr, sis->suspend_state[i], 4096);
+ ioaddr += 4096;
+ }
+
+ memset(sis->suspend_state[0], 0, 4096);
+
+ sis->irq = pci->irq;
+ pci_set_master(pci);
+
+ if (sis->codecs_present & SIS_PRIMARY_CODEC_PRESENT)
+ snd_ac97_resume(sis->ac97[0]);
+ if (sis->codecs_present & SIS_SECONDARY_CODEC_PRESENT)
+ snd_ac97_resume(sis->ac97[1]);
+ if (sis->codecs_present & SIS_TERTIARY_CODEC_PRESENT)
+ snd_ac97_resume(sis->ac97[2]);
+
+ snd_power_change_state(card, SNDRV_CTL_POWER_D0);
+ return 0;
+
+error:
+ snd_card_disconnect(card);
+ return -EIO;
+}
+#endif /* CONFIG_PM */
+
+static int sis_alloc_suspend(struct sis7019 *sis)
+{
+ int i;
+
+ /* We need 16K to store the internal wave engine state during a
+ * suspend, but we don't need it to be contiguous, so play nice
+ * with the memory system. We'll also use this area for a silence
+ * buffer.
+ */
+ for (i = 0; i < SIS_SUSPEND_PAGES; i++) {
+ sis->suspend_state[i] = kmalloc(4096, GFP_KERNEL);
+ if (!sis->suspend_state[i])
+ return -ENOMEM;
+ }
+ memset(sis->suspend_state[0], 0, 4096);
+
+ return 0;
+}
+
+static int __devinit sis_chip_create(struct snd_card *card,
+ struct pci_dev *pci)
+{
+ struct sis7019 *sis = card->private_data;
+ struct voice *voice;
+ static struct snd_device_ops ops = {
+ .dev_free = sis_dev_free,
+ };
+ int rc;
+ int i;
+
+ rc = pci_enable_device(pci);
+ if (rc)
+ goto error_out;
+
+ if (pci_set_dma_mask(pci, DMA_30BIT_MASK) < 0) {
+ printk(KERN_ERR "sis7019: architecture does not support "
+ "30-bit PCI busmaster DMA");
+ goto error_out_enabled;
+ }
+
+ memset(sis, 0, sizeof(*sis));
+ mutex_init(&sis->ac97_mutex);
+ spin_lock_init(&sis->voice_lock);
+ sis->card = card;
+ sis->pci = pci;
+ sis->irq = -1;
+ sis->ioport = pci_resource_start(pci, 0);
+
+ rc = pci_request_regions(pci, "SiS 7019");
+ if (rc) {
+ printk(KERN_ERR "sis7019: unable request regions\n");
+ goto error_out_enabled;
+ }
+
+ rc = -EIO;
+ sis->ioaddr = ioremap_nocache(pci_resource_start(pci, 1), 0x4000);
+ if (!sis->ioaddr) {
+ printk(KERN_ERR "sis7019: unable to remap MMIO, aborting\n");
+ goto error_out_cleanup;
+ }
+
+ rc = sis_alloc_suspend(sis);
+ if (rc < 0) {
+ printk(KERN_ERR "sis7019: unable to allocate state storage\n");
+ goto error_out_cleanup;
+ }
+
+ rc = sis_chip_init(sis);
+ if (rc)
+ goto error_out_cleanup;
+
+ if (request_irq(pci->irq, sis_interrupt, IRQF_DISABLED|IRQF_SHARED,
+ card->shortname, sis)) {
+ printk(KERN_ERR "unable to allocate irq %d\n", sis->irq);
+ goto error_out_cleanup;
+ }
+
+ sis->irq = pci->irq;
+ pci_set_master(pci);
+
+ for (i = 0; i < 64; i++) {
+ voice = &sis->voices[i];
+ voice->num = i;
+ voice->ctrl_base = SIS_PLAY_DMA_ADDR(sis->ioaddr, i);
+ voice->wave_base = SIS_WAVE_ADDR(sis->ioaddr, i);
+ }
+
+ voice = &sis->capture_voice;
+ voice->flags = VOICE_CAPTURE;
+ voice->num = SIS_CAPTURE_CHAN_AC97_PCM_IN;
+ voice->ctrl_base = SIS_CAPTURE_DMA_ADDR(sis->ioaddr, voice->num);
+
+ rc = snd_device_new(card, SNDRV_DEV_LOWLEVEL, sis, &ops);
+ if (rc)
+ goto error_out_cleanup;
+
+ snd_card_set_dev(card, &pci->dev);
+
+ return 0;
+
+error_out_cleanup:
+ sis_chip_free(sis);
+
+error_out_enabled:
+ pci_disable_device(pci);
+
+error_out:
+ return rc;
+}
+
+static int __devinit snd_sis7019_probe(struct pci_dev *pci,
+ const struct pci_device_id *pci_id)
+{
+ struct snd_card *card;
+ struct sis7019 *sis;
+ static int dev;
+ int rc;
+
+ rc = -ENODEV;
+ if (dev >= SNDRV_CARDS)
+ goto error_out;
+
+ rc = -ENOENT;
+ if (!enable[dev]) {
+ dev++;
+ goto error_out;
+ }
+
+ rc = -ENOMEM;
+ card = snd_card_new(index[dev], id[dev], THIS_MODULE, sizeof(*sis));
+ if (!card)
+ goto error_out;
+
+ strcpy(card->driver, "SiS 7019");
+ strcpy(card->shortname, "SiS 7019");
+ rc = sis_chip_create(card, pci);
+ if (rc)
+ goto card_error_out;
+
+ sis = card->private_data;
+
+ rc = sis_mixer_create(sis);
+ if (rc)
+ goto card_error_out;
+
+ rc = sis_pcm_create(sis);
+ if (rc)
+ goto card_error_out;
+
+ snprintf(card->longname, sizeof(card->longname),
+ "%s Audio Accelerator with %s at 0x%lx, irq %d",
+ card->shortname, snd_ac97_get_short_name(sis->ac97[0]),
+ sis->ioport, sis->irq);
+
+ rc = snd_card_register(card);
+ if (rc)
+ goto card_error_out;
+
+ pci_set_drvdata(pci, card);
+ dev++;
+ return 0;
+
+card_error_out:
+ snd_card_free(card);
+
+error_out:
+ return rc;
+}
+
+static void __devexit snd_sis7019_remove(struct pci_dev *pci)
+{
+ snd_card_free(pci_get_drvdata(pci));
+ pci_set_drvdata(pci, NULL);
+}
+
+static struct pci_driver sis7019_driver = {
+ .name = "SiS7019",
+ .id_table = snd_sis7019_ids,
+ .probe = snd_sis7019_probe,
+ .remove = __devexit_p(snd_sis7019_remove),
+
+#ifdef CONFIG_PM
+ .suspend = sis_suspend,
+ .resume = sis_resume,
+#endif
+};
+
+static int __init sis7019_init(void)
+{
+ return pci_register_driver(&sis7019_driver);
+}
+
+static void __exit sis7019_exit(void)
+{
+ pci_unregister_driver(&sis7019_driver);
+}
+
+module_init(sis7019_init);
+module_exit(sis7019_exit);
diff -r 17223a4918b4 pci/sis7019.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sound/pci/sis7019.h Wed Nov 28 01:39:33 2007 -0500
@@ -0,0 +1,342 @@
+#ifndef __sis7019_h__
+#define __sis7019_h__
+
+/*
+ * Definitions for SiS7019 Audio Accelerator
+ *
+ * Copyright (C) 2004-2007, David Dillow
+ * Written by David Dillow <dave thedillows org>
+ * Inspired by the Trident 4D-WaveDX/NX driver.
+ *
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * 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
+ */
+
+
+/* General Control Register */
+#define SIS_GCR 0x00
+#define SIS_GCR_MACRO_POWER_DOWN 0x80000000
+#define SIS_GCR_MODEM_ENABLE 0x00010000
+#define SIS_GCR_SOFTWARE_RESET 0x00000001
+
+/* General Interrupt Enable Register */
+#define SIS_GIER 0x04
+#define SIS_GIER_MODEM_TIMER_IRQ_ENABLE 0x00100000
+#define SIS_GIER_MODEM_RX_DMA_IRQ_ENABLE 0x00080000
+#define SIS_GIER_MODEM_TX_DMA_IRQ_ENABLE 0x00040000
+#define SIS_GIER_AC97_GPIO1_IRQ_ENABLE 0x00020000
+#define SIS_GIER_AC97_GPIO0_IRQ_ENABLE 0x00010000
+#define SIS_GIER_AC97_SAMPLE_TIMER_IRQ_ENABLE 0x00000010
+#define SIS_GIER_AUDIO_GLOBAL_TIMER_IRQ_ENABLE 0x00000008
+#define SIS_GIER_AUDIO_RECORD_DMA_IRQ_ENABLE 0x00000004
+#define SIS_GIER_AUDIO_PLAY_DMA_IRQ_ENABLE 0x00000002
+#define SIS_GIER_AUDIO_WAVE_ENGINE_IRQ_ENABLE 0x00000001
+
+/* General Interrupt Status Register */
+#define SIS_GISR 0x08
+#define SIS_GISR_MODEM_TIMER_IRQ_STATUS 0x00100000
+#define SIS_GISR_MODEM_RX_DMA_IRQ_STATUS 0x00080000
+#define SIS_GISR_MODEM_TX_DMA_IRQ_STATUS 0x00040000
+#define SIS_GISR_AC97_GPIO1_IRQ_STATUS 0x00020000
+#define SIS_GISR_AC97_GPIO0_IRQ_STATUS 0x00010000
+#define SIS_GISR_AC97_SAMPLE_TIMER_IRQ_STATUS 0x00000010
+#define SIS_GISR_AUDIO_GLOBAL_TIMER_IRQ_STATUS 0x00000008
+#define SIS_GISR_AUDIO_RECORD_DMA_IRQ_STATUS 0x00000004
+#define SIS_GISR_AUDIO_PLAY_DMA_IRQ_STATUS 0x00000002
+#define SIS_GISR_AUDIO_WAVE_ENGINE_IRQ_STATUS 0x00000001
+
+/* DMA Control Register */
+#define SIS_DMA_CSR 0x10
+#define SIS_DMA_CSR_PCI_SETTINGS 0x0000001d
+#define SIS_DMA_CSR_CONCURRENT_ENABLE 0x00000200
+#define SIS_DMA_CSR_PIPELINE_ENABLE 0x00000100
+#define SIS_DMA_CSR_RX_DRAIN_ENABLE 0x00000010
+#define SIS_DMA_CSR_RX_FILL_ENABLE 0x00000008
+#define SIS_DMA_CSR_TX_DRAIN_ENABLE 0x00000004
+#define SIS_DMA_CSR_TX_LOWPRI_FILL_ENABLE 0x00000002
+#define SIS_DMA_CSR_TX_HIPRI_FILL_ENABLE 0x00000001
+
+/* Playback Channel Start Registers */
+#define SIS_PLAY_START_A_REG 0x14
+#define SIS_PLAY_START_B_REG 0x18
+
+/* Playback Channel Stop Registers */
+#define SIS_PLAY_STOP_A_REG 0x1c
+#define SIS_PLAY_STOP_B_REG 0x20
+
+/* Recording Channel Start Register */
+#define SIS_RECORD_START_REG 0x24
+
+/* Recording Channel Stop Register */
+#define SIS_RECORD_STOP_REG 0x28
+
+/* Playback Interrupt Status Registers */
+#define SIS_PISR_A 0x2c
+#define SIS_PISR_B 0x30
+
+/* Recording Interrupt Status Register */
+#define SIS_RISR 0x34
+
+/* AC97 AC-link Playback Source Register */
+#define SIS_AC97_PSR 0x40
+#define SIS_AC97_PSR_MODEM_HEADSET_SRC_MIXER 0x0f000000
+#define SIS_AC97_PSR_MODEM_LINE2_SRC_MIXER 0x00f00000
+#define SIS_AC97_PSR_MODEM_LINE1_SRC_MIXER 0x000f0000
+#define SIS_AC97_PSR_PCM_LFR_SRC_MIXER 0x0000f000
+#define SIS_AC97_PSR_PCM_SURROUND_SRC_MIXER 0x00000f00
+#define SIS_AC97_PSR_PCM_CENTER_SRC_MIXER 0x000000f0
+#define SIS_AC97_PSR_PCM_LR_SRC_MIXER 0x0000000f
+
+/* AC97 AC-link Command Register */
+#define SIS_AC97_CMD 0x50
+#define SIS_AC97_CMD_DATA_MASK 0xffff0000
+#define SIS_AC97_CMD_REG_MASK 0x0000ff00
+#define SIS_AC97_CMD_CODEC3_READ 0x0000000d
+#define SIS_AC97_CMD_CODEC3_WRITE 0x0000000c
+#define SIS_AC97_CMD_CODEC2_READ 0x0000000b
+#define SIS_AC97_CMD_CODEC2_WRITE 0x0000000a
+#define SIS_AC97_CMD_CODEC_READ 0x00000009
+#define SIS_AC97_CMD_CODEC_WRITE 0x00000008
+#define SIS_AC97_CMD_CODEC_WARM_RESET 0x00000005
+#define SIS_AC97_CMD_CODEC_COLD_RESET 0x00000004
+#define SIS_AC97_CMD_DONE 0x00000000
+
+/* AC97 AC-link Semaphore Register */
+#define SIS_AC97_SEMA 0x54
+#define SIS_AC97_SEMA_BUSY 0x00000001
+#define SIS_AC97_SEMA_RELEASE 0x00000000
+
+/* AC97 AC-link Status Register */
+#define SIS_AC97_STATUS 0x58
+#define SIS_AC97_STATUS_AUDIO_D2_INACT_SECS 0x03f00000
+#define SIS_AC97_STATUS_MODEM_ALIVE 0x00002000
+#define SIS_AC97_STATUS_AUDIO_ALIVE 0x00001000
+#define SIS_AC97_STATUS_CODEC3_READY 0x00000400
+#define SIS_AC97_STATUS_CODEC2_READY 0x00000200
+#define SIS_AC97_STATUS_CODEC_READY 0x00000100
+#define SIS_AC97_STATUS_WARM_RESET 0x00000080
+#define SIS_AC97_STATUS_COLD_RESET 0x00000040
+#define SIS_AC97_STATUS_POWERED_DOWN 0x00000020
+#define SIS_AC97_STATUS_NORMAL 0x00000010
+#define SIS_AC97_STATUS_READ_EXPIRED 0x00000004
+#define SIS_AC97_STATUS_SEMAPHORE 0x00000002
+#define SIS_AC97_STATUS_BUSY 0x00000001
+
+/* AC97 AC-link Audio Configuration Register */
+#define SIS_AC97_CONF 0x5c
+#define SIS_AC97_CONF_AUDIO_ALIVE 0x80000000
+#define SIS_AC97_CONF_WARM_RESET_ENABLE 0x40000000
+#define SIS_AC97_CONF_PR6_ENABLE 0x20000000
+#define SIS_AC97_CONF_PR5_ENABLE 0x10000000
+#define SIS_AC97_CONF_PR4_ENABLE 0x08000000
+#define SIS_AC97_CONF_PR3_ENABLE 0x04000000
+#define SIS_AC97_CONF_PR2_PR7_ENABLE 0x02000000
+#define SIS_AC97_CONF_PR0_PR1_ENABLE 0x01000000
+#define SIS_AC97_CONF_AUTO_PM_ENABLE 0x00800000
+#define SIS_AC97_CONF_PCM_LFE_ENABLE 0x00080000
+#define SIS_AC97_CONF_PCM_SURROUND_ENABLE 0x00040000
+#define SIS_AC97_CONF_PCM_CENTER_ENABLE 0x00020000
+#define SIS_AC97_CONF_PCM_LR_ENABLE 0x00010000
+#define SIS_AC97_CONF_PCM_CAP_MIC_ENABLE 0x00002000
+#define SIS_AC97_CONF_PCM_CAP_LR_ENABLE 0x00001000
+#define SIS_AC97_CONF_PCM_CAP_MIC_FROM_CODEC3 0x00000200
+#define SIS_AC97_CONF_PCM_CAP_LR_FROM_CODEC3 0x00000100
+#define SIS_AC97_CONF_CODEC3_PM_VRM 0x00000080
+#define SIS_AC97_CONF_CODEC_PM_VRM 0x00000040
+#define SIS_AC97_CONF_CODEC3_VRA_ENABLE 0x00000020
+#define SIS_AC97_CONF_CODEC_VRA_ENABLE 0x00000010
+#define SIS_AC97_CONF_CODEC3_PM_EAC 0x00000008
+#define SIS_AC97_CONF_CODEC_PM_EAC 0x00000004
+#define SIS_AC97_CONF_CODEC3_EXISTS 0x00000002
+#define SIS_AC97_CONF_CODEC_EXISTS 0x00000001
+
+/* Playback Channel Sync Group registers */
+#define SIS_PLAY_SYNC_GROUP_A 0x80
+#define SIS_PLAY_SYNC_GROUP_B 0x84
+#define SIS_PLAY_SYNC_GROUP_C 0x88
+#define SIS_PLAY_SYNC_GROUP_D 0x8c
+#define SIS_MIXER_SYNC_GROUP 0x90
+
+/* Wave Engine Config and Control Register */
+#define SIS_WECCR 0xa0
+#define SIS_WECCR_TESTMODE_MASK 0x00300000
+#define SIS_WECCR_TESTMODE_NORMAL 0x00000000
+#define SIS_WECCR_TESTMODE_BYPASS_NSO_ALPHA 0x00100000
+#define SIS_WECCR_TESTMODE_BYPASS_FC 0x00200000
+#define SIS_WECCR_TESTMODE_BYPASS_WOL 0x00300000
+#define SIS_WECCR_RESONANCE_DELAY_MASK 0x00060000
+#define SIS_WECCR_RESONANCE_DELAY_NONE 0x00000000
+#define SIS_WECCR_RESONANCE_DELAY_FC_1F00 0x00020000
+#define SIS_WECCR_RESONANCE_DELAY_FC_1E00 0x00040000
+#define SIS_WECCR_RESONANCE_DELAY_FC_1C00 0x00060000
+#define SIS_WECCR_IGNORE_CHANNEL_PARMS 0x00010000
+#define SIS_WECCR_COMMAND_CHANNEL_ID_MASK 0x0003ff00
+#define SIS_WECCR_COMMAND_MASK 0x00000007
+#define SIS_WECCR_COMMAND_NONE 0x00000000
+#define SIS_WECCR_COMMAND_DONE 0x00000000
+#define SIS_WECCR_COMMAND_PAUSE 0x00000001
+#define SIS_WECCR_COMMAND_TOGGLE_VEG 0x00000002
+#define SIS_WECCR_COMMAND_TOGGLE_MEG 0x00000003
+#define SIS_WECCR_COMMAND_TOGGLE_VEG_MEG 0x00000004
+
+/* Wave Engine Volume Control Register */
+#define SIS_WEVCR 0xa4
+#define SIS_WEVCR_LEFT_MUSIC_ATTENUATION_MASK 0xff000000
+#define SIS_WEVCR_RIGHT_MUSIC_ATTENUATION_MASK 0x00ff0000
+#define SIS_WEVCR_LEFT_WAVE_ATTENUATION_MASK 0x0000ff00
+#define SIS_WEVCR_RIGHT_WAVE_ATTENUATION_MASK 0x000000ff
+
+/* Wave Engine Interrupt Status Registers */
+#define SIS_WEISR_A 0xa8
+#define SIS_WEISR_B 0xac
+
+
+/* Playback DMA parameters (paramter RAM) */
+#define SIS_PLAY_DMA_OFFSET 0x0000
+#define SIS_PLAY_DMA_SIZE 0x10
+#define SIS_PLAY_DMA_ADDR(addr, num) \
+ ((num * SIS_PLAY_DMA_SIZE) + (addr) + SIS_PLAY_DMA_OFFSET)
+
+#define SIS_PLAY_DMA_FORMAT_CSO 0x00
+#define SIS_PLAY_DMA_FORMAT_UNSIGNED 0x00080000
+#define SIS_PLAY_DMA_FORMAT_8BIT 0x00040000
+#define SIS_PLAY_DMA_FORMAT_MONO 0x00020000
+#define SIS_PLAY_DMA_CSO_MASK 0x0000ffff
+#define SIS_PLAY_DMA_BASE 0x04
+#define SIS_PLAY_DMA_CONTROL 0x08
+#define SIS_PLAY_DMA_STOP_AT_SSO 0x04000000
+#define SIS_PLAY_DMA_RELEASE 0x02000000
+#define SIS_PLAY_DMA_LOOP 0x01000000
+#define SIS_PLAY_DMA_INTR_AT_SSO 0x00080000
+#define SIS_PLAY_DMA_INTR_AT_ESO 0x00040000
+#define SIS_PLAY_DMA_INTR_AT_LEO 0x00020000
+#define SIS_PLAY_DMA_INTR_AT_MLP 0x00010000
+#define SIS_PLAY_DMA_LEO_MASK 0x0000ffff
+#define SIS_PLAY_DMA_SSO_ESO 0x0c
+#define SIS_PLAY_DMA_SSO_MASK 0xffff0000
+#define SIS_PLAY_DMA_ESO_MASK 0x0000ffff
+
+/* Capture DMA parameters (paramter RAM) */
+#define SIS_CAPTURE_DMA_OFFSET 0x0800
+#define SIS_CAPTURE_DMA_SIZE 0x10
+#define SIS_CAPTURE_DMA_ADDR(addr, num) \
+ ((num * SIS_CAPTURE_DMA_SIZE) + (addr) + SIS_CAPTURE_DMA_OFFSET)
+
+#define SIS_CAPTURE_CHAN_MIXER_ROUTE_BACK_0 0
+#define SIS_CAPTURE_CHAN_MIXER_ROUTE_BACK_1 1
+#define SIS_CAPTURE_CHAN_MIXER_ROUTE_BACK_2 2
+#define SIS_CAPTURE_CHAN_MIXER_ROUTE_BACK_3 3
+#define SIS_CAPTURE_CHAN_MIXER_ROUTE_BACK_4 4
+#define SIS_CAPTURE_CHAN_MIXER_ROUTE_BACK_5 5
+#define SIS_CAPTURE_CHAN_MIXER_ROUTE_BACK_6 6
+#define SIS_CAPTURE_CHAN_MIXER_ROUTE_BACK_7 7
+#define SIS_CAPTURE_CHAN_MIXER_ROUTE_BACK_8 8
+#define SIS_CAPTURE_CHAN_MIXER_ROUTE_BACK_9 9
+#define SIS_CAPTURE_CHAN_MIXER_ROUTE_BACK_10 10
+#define SIS_CAPTURE_CHAN_MIXER_ROUTE_BACK_11 11
+#define SIS_CAPTURE_CHAN_MIXER_ROUTE_BACK_12 12
+#define SIS_CAPTURE_CHAN_MIXER_ROUTE_BACK_13 13
+#define SIS_CAPTURE_CHAN_MIXER_ROUTE_BACK_14 14
+#define SIS_CAPTURE_CHAN_MIXER_ROUTE_BACK_15 15
+#define SIS_CAPTURE_CHAN_AC97_PCM_IN 16
+#define SIS_CAPTURE_CHAN_AC97_MIC_IN 17
+#define SIS_CAPTURE_CHAN_AC97_LINE1_IN 18
+#define SIS_CAPTURE_CHAN_AC97_LINE2_IN 19
+#define SIS_CAPTURE_CHAN_AC97_HANDSE_IN 20
+
+#define SIS_CAPTURE_DMA_FORMAT_CSO 0x00
+#define SIS_CAPTURE_DMA_MONO_MODE_MASK 0xc0000000
+#define SIS_CAPTURE_DMA_MONO_MODE_AVG 0x00000000
+#define SIS_CAPTURE_DMA_MONO_MODE_LEFT 0x40000000
+#define SIS_CAPTURE_DMA_MONO_MODE_RIGHT 0x80000000
+#define SIS_CAPTURE_DMA_FORMAT_UNSIGNED 0x00080000
+#define SIS_CAPTURE_DMA_FORMAT_8BIT 0x00040000
+#define SIS_CAPTURE_DMA_FORMAT_MONO 0x00020000
+#define SIS_CAPTURE_DMA_CSO_MASK 0x0000ffff
+#define SIS_CAPTURE_DMA_BASE 0x04
+#define SIS_CAPTURE_DMA_CONTROL 0x08
+#define SIS_CAPTURE_DMA_STOP_AT_SSO 0x04000000
+#define SIS_CAPTURE_DMA_RELEASE 0x02000000
+#define SIS_CAPTURE_DMA_LOOP 0x01000000
+#define SIS_CAPTURE_DMA_INTR_AT_LEO 0x00020000
+#define SIS_CAPTURE_DMA_INTR_AT_MLP 0x00010000
+#define SIS_CAPTURE_DMA_LEO_MASK 0x0000ffff
+#define SIS_CAPTURE_DMA_RESERVED 0x0c
+
+
+/* Mixer routing list start pointer (parameter RAM) */
+#define SIS_MIXER_START_OFFSET 0x1000
+#define SIS_MIXER_START_SIZE 0x04
+#define SIS_MIXER_START_ADDR(addr, num) \
+ ((num * SIS_MIXER_START_SIZE) + (addr) + SIS_MIXER_START_OFFSET)
+
+#define SIS_MIXER_START_MASK 0x0000007f
+
+/* Mixer routing table (parameter RAM) */
+#define SIS_MIXER_OFFSET 0x1400
+#define SIS_MIXER_SIZE 0x04
+#define SIS_MIXER_ADDR(addr, num) \
+ ((num * SIS_MIXER_SIZE) + (addr) + SIS_MIXER_OFFSET)
+
+#define SIS_MIXER_RIGHT_ATTENUTATION_MASK 0xff000000
+#define SIS_MIXER_RIGHT_NO_ATTEN 0xff000000
+#define SIS_MIXER_LEFT_ATTENUTATION_MASK 0x00ff0000
+#define SIS_MIXER_LEFT_NO_ATTEN 0x00ff0000
+#define SIS_MIXER_NEXT_ENTRY_MASK 0x00007f00
+#define SIS_MIXER_NEXT_ENTRY_NONE 0x00000000
+#define SIS_MIXER_DEST_MASK 0x0000007f
+#define SIS_MIXER_DEST_0 0x00000020
+#define SIS_MIXER_DEST_1 0x00000021
+#define SIS_MIXER_DEST_2 0x00000022
+#define SIS_MIXER_DEST_3 0x00000023
+#define SIS_MIXER_DEST_4 0x00000024
+#define SIS_MIXER_DEST_5 0x00000025
+#define SIS_MIXER_DEST_6 0x00000026
+#define SIS_MIXER_DEST_7 0x00000027
+#define SIS_MIXER_DEST_8 0x00000028
+#define SIS_MIXER_DEST_9 0x00000029
+#define SIS_MIXER_DEST_10 0x0000002a
+#define SIS_MIXER_DEST_11 0x0000002b
+#define SIS_MIXER_DEST_12 0x0000002c
+#define SIS_MIXER_DEST_13 0x0000002d
+#define SIS_MIXER_DEST_14 0x0000002e
+#define SIS_MIXER_DEST_15 0x0000002f
+
+/* Wave Engine Control Parameters (parameter RAM) */
+#define SIS_WAVE_OFFSET 0x2000
+#define SIS_WAVE_SIZE 0x40
+#define SIS_WAVE_ADDR(addr, num) \
+ ((num * SIS_WAVE_SIZE) + (addr) + SIS_WAVE_OFFSET)
+
+#define SIS_WAVE_GENERAL 0x00
+#define SIS_WAVE_GENERAL_WAVE_VOLUME 0x80000000
+#define SIS_WAVE_GENERAL_MUSIC_VOLUME 0x00000000
+#define SIS_WAVE_GENERAL_VOLUME_MASK 0x7f000000
+#define SIS_WAVE_GENERAL_ARTICULATION 0x04
+#define SIS_WAVE_GENERAL_ARTICULATION_DELTA_MASK 0x3fff0000
+#define SIS_WAVE_ARTICULATION 0x08
+#define SIS_WAVE_TIMER 0x0c
+#define SIS_WAVE_GENERATOR 0x10
+#define SIS_WAVE_CHANNEL_CONTROL 0x14
+#define SIS_WAVE_CHANNEL_CONTROL_FIRST_SAMPLE 0x80000000
+#define SIS_WAVE_CHANNEL_CONTROL_AMP_ENABLE 0x40000000
+#define SIS_WAVE_CHANNEL_CONTROL_FILTER_ENABLE 0x20000000
+#define SIS_WAVE_CHANNEL_CONTROL_INTERPOLATE_ENABLE 0x10000000
+#define SIS_WAVE_LFO_EG_CONTROL 0x18
+#define SIS_WAVE_LFO_EG_CONTROL_2 0x1c
+#define SIS_WAVE_LFO_EG_CONTROL_3 0x20
+#define SIS_WAVE_LFO_EG_CONTROL_4 0x24
+
+#endif /* __sis7019_h__ */
linux-2.6-at76.patch:
--- NEW FILE linux-2.6-at76.patch ---
commit 38ec6fbd236318179e28c71bc1b3dc94166e4be2
Author: Pavel Roskin <proski gnu org>
Date: Mon Feb 4 00:05:19 2008 -0500
at76_usb: Add ID for Uniden PCW100
Tested and reported by Lior Silberman.
Signed-off-by: Pavel Roskin <proski gnu org>
Signed-off-by: John W. Linville <linville tuxdriver com>
commit 4ed58b00a2df9772cfa631f53af52c38207d78ac
Author: Pavel Roskin <proski gnu org>
Date: Sun Sep 30 14:41:25 2007 -0400
[PATCH] at76_usb: Add ID for at76c503a based CNETUSB611
Signed-off-by: Pavel Roskin <proski gnu org>
Signed-off-by: John W. Linville <linville tuxdriver com>
commit 3a39b0c26c19b4f26ab90f8cd170e68da3c8fb91
Author: Pavel Roskin <proski gnu org>
Date: Sun Sep 30 14:41:18 2007 -0400
[PATCH] at76_usb: Bump version to 0.17
Signed-off-by: Pavel Roskin <proski gnu org>
Signed-off-by: John W. Linville <linville tuxdriver com>
commit 69a965e9dde88c1dec49a0e840020bbdfc2263ad
Author: Pavel Roskin <proski gnu org>
Date: Sun Sep 30 14:41:12 2007 -0400
[PATCH] at76_usb: Use ETH_P_802_2 in monitor mode
It's used by most other wireless drivers, including mac80211.
ETH_P_80211_RAW is obsolete.
Signed-off-by: Pavel Roskin <proski gnu org>
Signed-off-by: John W. Linville <linville tuxdriver com>
commit e007ed4c5328f857201d66c8564978bd4150a9a5
Author: Pavel Roskin <proski gnu org>
Date: Sun Sep 30 14:41:06 2007 -0400
[PATCH] at76_usb: Be more verbose on startup
Promote some debug messages from at76_dbg() to unconditional KERN_DEBUG.
Use dev_printk() before the device is registered, as "wlan%d" doesn't
identify the device uniquely.
Print firmware name and version when it's loaded from file. Print
firmware version reported by the card. Print USB address and network
device name on the same line to help identifying the device.
Signed-off-by: Pavel Roskin <proski gnu org>
Signed-off-by: John W. Linville <linville tuxdriver com>
commit 84d9a4914d2f678728b0b9a4c4b360e93b2e2efa
Author: Pavel Roskin <proski gnu org>
Date: Sun Sep 30 14:40:59 2007 -0400
[PATCH] at76_usb: Use dev_printk() where possible
dev_printk() prints the USB device name in addition to the driver name,
which makes it easier to understand the diagnostics in case of multiple
devices.
Use &interface->dev, as it's more specific and includes the driver name,
but use &udev->dev if interface is not available.
Signed-off-by: Pavel Roskin <proski gnu org>
Signed-off-by: John W. Linville <linville tuxdriver com>
commit 46e958f2e0334bfeb1436d8066e1797804212178
Author: Pavel Roskin <proski gnu org>
Date: Sun Sep 30 14:40:53 2007 -0400
[PATCH] at76_usb: Remove incorrect firmware version check
The major version of the firmware reported by the device can mismatch
the version of the originally loaded firmware, as it is the case for
Belkin F5D6050.
Remove this check and assume the firmware to be working as long that the
external firmware download didn't fail and the firmware version could be
read at all.
Reported by Corey Pappas <pappascd gmail com>
Signed-off-by: Pavel Roskin <proski gnu org>
Signed-off-by: John W. Linville <linville tuxdriver com>
commit cbf56decc3dd24be59bdcd7af14ae6b6fc1d7265
Author: Pavel Roskin <proski gnu org>
Date: Sun Sep 30 14:40:47 2007 -0400
[PATCH] at76_usb: Revert to network device names starting with "wlan"
The change to the default "eth" in 0.16 was unnecessary and broke some
setups. Reported by Mark Sansome <msansome troodos demon co uk>
Signed-off-by: Pavel Roskin <proski gnu org>
Signed-off-by: John W. Linville <linville tuxdriver com>
commit 73363e219953a6bcafa0087b415c0ce154a13940
Author: Pavel Roskin <proski gnu org>
Date: Sun Sep 30 14:40:40 2007 -0400
[PATCH] at76_usb: Add ID for Corega Wireless LAN USB-11 mini and mini2
Original patch by Weihua Yao <weihuayao gmail com>
Signed-off-by: Pavel Roskin <proski gnu org>
Signed-off-by: John W. Linville <linville tuxdriver com>
commit 65e5ad191757d5febb31e97a8a08dbd672d0662d
Author: Pavel Roskin <proski gnu org>
Date: Sun Sep 30 14:40:34 2007 -0400
[PATCH] at76_usb: Avoid dealing with milliseconds when possible, use jiffies
Signed-off-by: Pavel Roskin <proski gnu org>
Signed-off-by: John W. Linville <linville tuxdriver com>
commit 8f3811adf092d19f14111166af05f10cb2efa651
Author: Pavel Roskin <proski gnu org>
Date: Sun Sep 30 14:40:27 2007 -0400
[PATCH] at76_usb: Move some parts from at76_usb.h to at76_usb.c
Don't include anything from at76_usb.h. Keep DRIVER_NAME and
DRIVER_VERSION together. Define at76_dbg() after DRIVER_NAME.
Signed-off-by: Pavel Roskin <proski gnu org>
Signed-off-by: John W. Linville <linville tuxdriver com>
commit 0048a3f2c0de2f6ba969731f51eaaa73b3e168e2
Author: Pavel Roskin <proski gnu org>
Date: Sun Sep 30 14:40:21 2007 -0400
[PATCH] at76_usb: Remove unneeded memset() calls
Use kzalloc for bss table entries. priv is already zeroized, no need to
do it again.
Signed-off-by: Pavel Roskin <proski gnu org>
Signed-off-by: John W. Linville <linville tuxdriver com>
commit 20eab45fc567b85f8aaa131eceb8d53ac14d3fd6
Author: Pavel Roskin <proski gnu org>
Date: Sun Sep 30 14:40:15 2007 -0400
[PATCH] at76_usb: Clean reserved tx area for mgmt frames like it's done for data
Signed-off-by: Pavel Roskin <proski gnu org>
Signed-off-by: John W. Linville <linville tuxdriver com>
commit b96c9fd4b3770d5b731ed3d207644b2ffec80313
Author: Pavel Roskin <proski gnu org>
Date: Sun Sep 30 14:40:08 2007 -0400
[PATCH] at76_usb: Make it clear that management frames are sent at 1Mbps
Signed-off-by: Pavel Roskin <proski gnu org>
Signed-off-by: John W. Linville <linville tuxdriver com>
commit 6abdf0d9679fb3cc0b2ed539e24cbba058f33043
Author: Pavel Roskin <proski gnu org>
Date: Sun Sep 30 14:40:02 2007 -0400
[PATCH] at76_usb: Eliminate variables used only in at76_dbg()
Make it possible to disable at76_dbg() at the compile time without
introducing any warnings.
Signed-off-by: Pavel Roskin <proski gnu org>
Signed-off-by: John W. Linville <linville tuxdriver com>
commit 53c4d65cd1f4455b6d0c6ce605a6853e9108c6ae
Author: Pavel Roskin <proski gnu org>
Date: Sun Sep 30 14:39:55 2007 -0400
[PATCH] at76_usb: Use string precision to avoid line termination
In particular, don't extend ESSID to 33 bytes.
Signed-off-by: Pavel Roskin <proski gnu org>
Signed-off-by: John W. Linville <linville tuxdriver com>
commit 2a000a0fb3a21674791023759e24e1bdc3c197ef
Author: Pavel Roskin <proski gnu org>
Date: Sun Sep 30 14:39:49 2007 -0400
[PATCH] at76_usb: Stop worrying about line termination in ethtool info
The driver's responsibility is not to overwrite the buffer and not to
leak kernel data. Line termination is the userspace responsibility.
[...6542 lines suppressed...]
+ free_netdev(priv->netdev); /* priv is in netdev */
+
+ at76_dbg(DBG_PROC_ENTRY, "%s: EXIT", __func__);
+}
+
+static int at76_probe(struct usb_interface *interface,
+ const struct usb_device_id *id)
+{
+ 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) {
+ dev_printk(KERN_ERR, &interface->dev,
+ "cannot handle a device in HW_CONFIG_MODE\n");
+ ret = -EBUSY;
+ goto error;
+ }
+
+ if (op_mode != OPMODE_NORMAL_NIC_WITH_FLASH
+ && op_mode != OPMODE_NORMAL_NIC_WITHOUT_FLASH) {
+ /* download internal firmware part */
+ dev_printk(KERN_DEBUG, &interface->dev,
+ "downloading internal firmware\n");
+ ret = at76_load_internal_fw(udev, fwe);
+ if (ret < 0) {
+ dev_printk(KERN_ERR, &interface->dev,
+ "error %d downloading internal firmware\n",
+ 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) {
+ dev_printk(KERN_DEBUG, &interface->dev,
+ "downloading external firmware\n");
+
+ 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) {
+ dev_printk(KERN_ERR, &interface->dev,
+ "error %d getting firmware version\n", ret);
+ 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);
+ dev_printk(KERN_INFO, &interface->dev, "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)
+ printk(KERN_ERR DRIVER_NAME
+ ": usb_register failed (status %d)\n", 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.24.noarch/drivers/net/wireless/Kconfig.orig linux-2.6.24.noarch/drivers/net/wireless/Kconfig
--- linux-2.6.24.noarch/drivers/net/wireless/Kconfig.orig 2008-02-05 22:45:16.000000000 -0500
+++ linux-2.6.24.noarch/drivers/net/wireless/Kconfig 2008-02-05 22:46:17.000000000 -0500
@@ -451,6 +451,14 @@ config PCMCIA_ATMEL
Enable support for PCMCIA cards containing the
Atmel at76c502 and at76c504 chips.
+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 AIRO_CS
tristate "Cisco/Aironet 34X/35X/4500/4800 PCMCIA cards"
depends on PCMCIA && (BROKEN || !M32R) && WLAN_80211
linux-2.6-ath5k-use-soft-wep.patch:
--- NEW FILE linux-2.6-ath5k-use-soft-wep.patch ---
diff -up linux-2.6.23.noarch/drivers/net/wireless/ath5k/base.c.orig linux-2.6.23.noarch/drivers/net/wireless/ath5k/base.c
--- linux-2.6.23.noarch/drivers/net/wireless/ath5k/base.c.orig 2007-12-01 13:00:52.000000000 -0500
+++ linux-2.6.23.noarch/drivers/net/wireless/ath5k/base.c 2007-12-01 13:01:04.000000000 -0500
@@ -2830,7 +2830,6 @@ ath5k_set_key(struct ieee80211_hw *hw, e
switch(key->alg) {
case ALG_WEP:
- break;
case ALG_TKIP:
case ALG_CCMP:
return -EOPNOTSUPP;
linux-2.6-compile-fix-gcc-43.patch:
--- NEW FILE linux-2.6-compile-fix-gcc-43.patch ---
--- linux-2.6.24.noarch.orig/include/linux/time.h
+++ linux-2.6.24.noarch/include/linux/time.h
@@ -169,7 +169,7 @@ extern struct timeval ns_to_timeval(cons
* @a: pointer to timespec to be incremented
* @ns: unsigned nanoseconds value to be added
*/
-static inline void timespec_add_ns(struct timespec *a, u64 ns)
+static inline void timespec_add_ns(struct timespec *a, volatile u64 ns)
{
ns += a->tv_nsec;
while(unlikely(ns >= NSEC_PER_SEC)) {
--- a/include/linux/moduleparam.h
+++ b/include/linux/moduleparam.h
@@ -62,6 +62,15 @@ struct kparam_array
void *elem;
};
+/* On some platforms relocations to global data cannot go into read-only
+ sections, so 'const' makes no sense and even causes compile failures
+ with some compilers. */
+#if defined(CONFIG_ALPHA) || defined(CONFIG_IA64) || defined(CONFIG_PPC64)
+#define __moduleparam_const
+#else
+#define __moduleparam_const const
+#endif
+
/* This is the fundamental function for registering boot/module
parameters. perm sets the visibility in sysfs: 000 means it's
not there, read bits mean it's readable, write bits mean it's
@@ -71,7 +80,7 @@ struct kparam_array
static int __param_perm_check_##name __attribute__((unused)) = \
BUILD_BUG_ON_ZERO((perm) < 0 || (perm) > 0777 || ((perm) & 2)); \
static const char __param_str_##name[] = prefix #name; \
- static struct kernel_param const __param_##name \
+ static struct kernel_param __moduleparam_const __param_##name \
__attribute_used__ \
__attribute__ ((unused,__section__ ("__param"),aligned(sizeof(void *)))) \
= { __param_str_##name, perm, set, get, { arg } }
--- linux-2.6.24.noarch.orig/include/linux/module.h
+++ linux-2.6.24.noarch/include/linux/module.h
@@ -30,6 +30,15 @@
#define MODULE_NAME_LEN (64 - sizeof(unsigned long))
+/* On some platforms relocations to global data cannot go into read-only
+ sections, so 'const' makes no sense and even causes compile failures
+ with some compilers. */
+#if defined(CONFIG_ALPHA) || defined(CONFIG_IA64) || defined(CONFIG_PPC64)
+#define __ksym_const
+#else
+#define __ksym_const const
+#endif
+
struct kernel_symbol
{
unsigned long value;
@@ -192,7 +201,7 @@ void *__symbol_get_gpl(const char *symbo
static const char __kstrtab_##sym[] \
__attribute__((section("__ksymtab_strings"))) \
= MODULE_SYMBOL_PREFIX #sym; \
- static const struct kernel_symbol __ksymtab_##sym \
+ static __ksym_const struct kernel_symbol __ksymtab_##sym \
__attribute_used__ \
__attribute__((section("__ksymtab" sec), unused)) \
= { (unsigned long)&sym, __kstrtab_##sym }
linux-2.6-compile-fixes.patch:
--- NEW FILE linux-2.6-compile-fixes.patch ---
#
# Small compile fixes (For more involved fixes, please use a separate patch).
#
# Please add the errors from gcc before the diffs to save others having
# to do a compile to figure out what your diff is fixing. Thanks.
#
linux-2.6-dcdbas-autoload.patch:
--- NEW FILE linux-2.6-dcdbas-autoload.patch ---
diff --git a/drivers/firmware/dcdbas.c b/drivers/firmware/dcdbas.c
index 18cdcb3..1636806 100644
--- a/drivers/firmware/dcdbas.c
+++ b/drivers/firmware/dcdbas.c
@@ -658,4 +658,5 @@ MODULE_DESCRIPTION(DRIVER_DESCRIPTION " (version " DRIVER_VERSION ")");
MODULE_VERSION(DRIVER_VERSION);
MODULE_AUTHOR("Dell Inc.");
MODULE_LICENSE("GPL");
-
+/* Any System or BIOS claiming to be by Dell */
+MODULE_ALIAS("dmi:*:[bs]vnD[Ee][Ll][Ll]*:*");
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
*(u32 *) value = readl(virt_addr);
break;
default:
+ printk(KERN_ERR PREFIX
+ "writing %d bits to %p\n", (int)width, virt_addr);
BUG();
}
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
@@ -373,7 +373,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 sighand_struct {
atomic_t count;
linux-2.6-drm-add-i915-radeon-mdt.patch:
--- NEW FILE linux-2.6-drm-add-i915-radeon-mdt.patch ---
diff --git a/drivers/char/drm/i915_drv.c b/drivers/char/drm/i915_drv.c
index 0f9c1f1..1be5795 100644
--- a/drivers/char/drm/i915_drv.c
+++ b/drivers/char/drm/i915_drv.c
@@ -37,6 +37,8 @@
static struct pci_device_id pciidlist[] = {
i915_PCI_IDS
};
+MODULE_DEVICE_TABLE(pci, pciidlist);
+
static struct drm_fence_driver i915_fence_driver = {
.num_classes = 1,
.wrap_diff = (1U << (BREADCRUMB_BITS - 1)),
diff --git a/drivers/char/drm/radeon_drv.c b/drivers/char/drm/radeon_drv.c
index 349ac3d..1be40f5 100644
--- a/drivers/char/drm/radeon_drv.c
+++ b/drivers/char/drm/radeon_drv.c
@@ -56,6 +56,8 @@ static struct pci_device_id pciidlist[] = {
radeon_PCI_IDS
};
+MODULE_DEVICE_TABLE(pci, pciidlist);
+
static struct drm_driver driver = {
.driver_features =
DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG |
linux-2.6-drm-mm.patch:
--- NEW FILE linux-2.6-drm-mm.patch ---
diff --git a/drivers/char/drm/Kconfig b/drivers/char/drm/Kconfig
index ba3058d..610d6fd 100644
--- a/drivers/char/drm/Kconfig
+++ b/drivers/char/drm/Kconfig
@@ -38,7 +38,7 @@ config DRM_RADEON
Choose this option if you have an ATI Radeon graphics card. There
are both PCI and AGP versions. You don't need to choose this to
run the Radeon in plain VGA mode.
-
+
If M is selected, the module will be called radeon.
config DRM_I810
@@ -71,9 +71,9 @@ config DRM_I915
852GM, 855GM 865G or 915G integrated graphics. If M is selected, the
module will be called i915. AGP support is required for this driver
to work. This driver is used by the Intel driver in X.org 6.8 and
- XFree86 4.4 and above. If unsure, build this and i830 as modules and
+ XFree86 4.4 and above. If unsure, build this and i830 as modules and
the X server will load the correct one.
-
+
endchoice
config DRM_MGA
@@ -88,7 +88,7 @@ config DRM_SIS
tristate "SiS video cards"
depends on DRM && AGP
help
- Choose this option if you have a SiS 630 or compatible video
+ Choose this option if you have a SiS 630 or compatible video
chipset. If M is selected the module will be called sis. AGP
support is required for this driver to work.
@@ -105,4 +105,3 @@ config DRM_SAVAGE
help
Choose this option if you have a Savage3D/4/SuperSavage/Pro/Twister
chipset. If M is selected the module will be called savage.
-
diff --git a/drivers/char/drm/Makefile b/drivers/char/drm/Makefile
index 6915a05..85c4f9e 100644
--- a/drivers/char/drm/Makefile
+++ b/drivers/char/drm/Makefile
@@ -6,14 +6,15 @@ drm-objs := drm_auth.o drm_bufs.o drm_context.o drm_dma.o drm_drawable.o \
drm_drv.o drm_fops.o drm_ioctl.o drm_irq.o \
drm_lock.o drm_memory.o drm_proc.o drm_stub.o drm_vm.o \
drm_agpsupport.o drm_scatter.o ati_pcigart.o drm_pci.o \
- drm_sysfs.o drm_hashtab.o drm_sman.o drm_mm.o
+ drm_sysfs.o drm_hashtab.o drm_sman.o drm_mm.o drm_object.o \
+ drm_fence.o drm_ttm.o drm_bo.o drm_bo_move.o drm_bo_lock.o
tdfx-objs := tdfx_drv.o
r128-objs := r128_drv.o r128_cce.o r128_state.o r128_irq.o
mga-objs := mga_drv.o mga_dma.o mga_state.o mga_warp.o mga_irq.o
i810-objs := i810_drv.o i810_dma.o
i830-objs := i830_drv.o i830_dma.o i830_irq.o
-i915-objs := i915_drv.o i915_dma.o i915_irq.o i915_mem.o
+i915-objs := i915_drv.o i915_dma.o i915_irq.o i915_mem.o i915_fence.o i915_buffer.o
radeon-objs := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o radeon_irq.o r300_cmdbuf.o
sis-objs := sis_drv.o sis_mm.o
savage-objs := savage_drv.o savage_bci.o savage_state.o
@@ -38,5 +39,3 @@ obj-$(CONFIG_DRM_I915) += i915.o
obj-$(CONFIG_DRM_SIS) += sis.o
obj-$(CONFIG_DRM_SAVAGE)+= savage.o
obj-$(CONFIG_DRM_VIA) +=via.o
-
-
diff --git a/drivers/char/drm/README.drm b/drivers/char/drm/README.drm
index af74cd7..b5b3327 100644
--- a/drivers/char/drm/README.drm
+++ b/drivers/char/drm/README.drm
@@ -41,4 +41,3 @@ For specific information about kernel-level support, see:
A Security Analysis of the Direct Rendering Infrastructure
http://dri.sourceforge.net/doc/security_low_level.html
-
diff --git a/drivers/char/drm/drm.h b/drivers/char/drm/drm.h
index 82fb3d0..c6686f1 100644
--- a/drivers/char/drm/drm.h
+++ b/drivers/char/drm/drm.h
@@ -190,6 +190,7 @@ enum drm_map_type {
_DRM_AGP = 3, /**< AGP/GART */
_DRM_SCATTER_GATHER = 4, /**< Scatter/gather memory for PCI DMA */
_DRM_CONSISTENT = 5, /**< Consistent memory for PCI DMA */
+ _DRM_TTM = 6
};
/**
@@ -202,7 +203,8 @@ enum drm_map_flags {
_DRM_KERNEL = 0x08, /**< kernel requires access */
_DRM_WRITE_COMBINING = 0x10, /**< use write-combining if available */
_DRM_CONTAINS_LOCK = 0x20, /**< SHM page that contains lock */
- _DRM_REMOVABLE = 0x40 /**< Removable mapping */
+ _DRM_REMOVABLE = 0x40, /**< Removable mapping */
+ _DRM_DRIVER = 0x80 /**< Managed by driver */
};
struct drm_ctx_priv_map {
@@ -470,6 +472,7 @@ struct drm_irq_busid {
enum drm_vblank_seq_type {
_DRM_VBLANK_ABSOLUTE = 0x0, /**< Wait for specific vblank sequence number */
_DRM_VBLANK_RELATIVE = 0x1, /**< Wait for given number of vblanks */
+ _DRM_VBLANK_FLIP = 0x8000000, /**< Scheduled buffer swap should flip */
_DRM_VBLANK_NEXTONMISS = 0x10000000, /**< If missed, wait for next vblank */
_DRM_VBLANK_SECONDARY = 0x20000000, /**< Secondary display controller */
_DRM_VBLANK_SIGNAL = 0x40000000 /**< Send signal instead of blocking */
@@ -572,6 +575,271 @@ struct drm_set_version {
int drm_dd_minor;
};
+#define DRM_FENCE_FLAG_EMIT 0x00000001
+#define DRM_FENCE_FLAG_SHAREABLE 0x00000002
+#define DRM_FENCE_FLAG_WAIT_LAZY 0x00000004
+#define DRM_FENCE_FLAG_WAIT_IGNORE_SIGNALS 0x00000008
+#define DRM_FENCE_FLAG_NO_USER 0x00000010
+
+/* Reserved for driver use */
+#define DRM_FENCE_MASK_DRIVER 0xFF000000
+
+#define DRM_FENCE_TYPE_EXE 0x00000001
+
+struct drm_fence_arg {
+ unsigned int handle;
+ unsigned int fence_class;
+ unsigned int type;
+ unsigned int flags;
+ unsigned int signaled;
+ unsigned int error;
+ unsigned int sequence;
+ unsigned int pad64;
+ uint64_t expand_pad[2]; /*Future expansion */
+};
+
+/* Buffer permissions, referring to how the GPU uses the buffers.
+ * these translate to fence types used for the buffers.
+ * Typically a texture buffer is read, A destination buffer is write and
+ * a command (batch-) buffer is exe. Can be or-ed together.
+ */
+
+#define DRM_BO_FLAG_READ (1ULL << 0)
+#define DRM_BO_FLAG_WRITE (1ULL << 1)
+#define DRM_BO_FLAG_EXE (1ULL << 2)
+
+/*
+ * Status flags. Can be read to determine the actual state of a buffer.
+ * Can also be set in the buffer mask before validation.
+ */
+
+/*
+ * Mask: Never evict this buffer. Not even with force.
+ * This type of buffer is only available to root and must be manually
+ * removed before buffer manager shutdown or lock.
+ * Flags: Acknowledge
+ */
+#define DRM_BO_FLAG_NO_EVICT (1ULL << 4)
+
+/*
+ * Mask: Require that the buffer is placed in mappable memory when validated.
+ * If not set the buffer may or may not be in mappable memory when validated.
+ * Flags: If set, the buffer is in mappable memory.
+ */
+#define DRM_BO_FLAG_MAPPABLE (1ULL << 5)
+
+/* Mask: The buffer should be shareable with other processes.
+ * Flags: The buffer is shareable with other processes.
+ */
+#define DRM_BO_FLAG_SHAREABLE (1ULL << 6)
+
+/* Mask: If set, place the buffer in cache-coherent memory if available.
+ * If clear, never place the buffer in cache coherent memory if validated.
+ * Flags: The buffer is currently in cache-coherent memory.
+ */
+#define DRM_BO_FLAG_CACHED (1ULL << 7)
+
+/* Mask: Make sure that every time this buffer is validated,
+ * it ends up on the same location provided that the memory mask
+ * is the same.
+ * The buffer will also not be evicted when claiming space for
+ * other buffers. Basically a pinned buffer but it may be thrown out as
+ * part of buffer manager shutdown or locking.
+ * Flags: Acknowledge.
+ */
+#define DRM_BO_FLAG_NO_MOVE (1ULL << 8)
+
+/* Mask: Make sure the buffer is in cached memory when mapped
+ * Flags: Acknowledge.
+ * Buffers allocated with this flag should not be used for suballocators
+ * This type may have issues on CPUs with over-aggressive caching
+ * http://marc.info/?l=linux-kernel&m=102376926732464&w=2
+ */
+#define DRM_BO_FLAG_CACHED_MAPPED (1ULL << 19)
+
+
+/* Mask: Force DRM_BO_FLAG_CACHED flag strictly also if it is set.
+ * Flags: Acknowledge.
+ */
+#define DRM_BO_FLAG_FORCE_CACHING (1ULL << 13)
+
+/*
[...12635 lines suppressed...]
+ if (sync->engine >= VIA_NUM_BLIT_ENGINES)
return -EINVAL;
err = via_dmablit_sync(dev, sync->sync_handle, sync->engine);
@@ -796,15 +796,15 @@ via_dma_blit_sync( struct drm_device *dev, void *data, struct drm_file *file_pri
return err;
}
-
+
/*
* Queue a blit and hand back a handle to be used for sync. This IOCTL may be interrupted by a signal
- * while waiting for a free slot in the blit queue. In that case it returns with -EAGAIN and should
+ * while waiting for a free slot in the blit queue. In that case it returns with -EAGAIN and should
* be reissued. See the above IOCTL code.
*/
-int
+int
via_dma_blit( struct drm_device *dev, void *data, struct drm_file *file_priv )
{
drm_via_dmablit_t *xfer = data;
diff --git a/drivers/char/drm/via_dmablit.h b/drivers/char/drm/via_dmablit.h
index 6f6a513..7408a54 100644
--- a/drivers/char/drm/via_dmablit.h
+++ b/drivers/char/drm/via_dmablit.h
@@ -1,5 +1,5 @@
/* via_dmablit.h -- PCI DMA BitBlt support for the VIA Unichrome/Pro
- *
+ *
* Copyright 2005 Thomas Hellstrom.
* All Rights Reserved.
*
@@ -17,12 +17,12 @@
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE.
*
- * Authors:
+ * Authors:
* Thomas Hellstrom.
* Register info from Digeo Inc.
*/
@@ -67,7 +67,7 @@ typedef struct _drm_via_blitq {
unsigned cur;
unsigned num_free;
unsigned num_outstanding;
- unsigned long end;
+ unsigned long end;
int aborting;
int is_active;
drm_via_sg_info_t *blits[VIA_NUM_BLIT_SLOTS];
@@ -77,46 +77,46 @@ typedef struct _drm_via_blitq {
struct work_struct wq;
struct timer_list poll_timer;
} drm_via_blitq_t;
-
-/*
+
+/*
* PCI DMA Registers
* Channels 2 & 3 don't seem to be implemented in hardware.
*/
-
-#define VIA_PCI_DMA_MAR0 0xE40 /* Memory Address Register of Channel 0 */
-#define VIA_PCI_DMA_DAR0 0xE44 /* Device Address Register of Channel 0 */
-#define VIA_PCI_DMA_BCR0 0xE48 /* Byte Count Register of Channel 0 */
-#define VIA_PCI_DMA_DPR0 0xE4C /* Descriptor Pointer Register of Channel 0 */
-
-#define VIA_PCI_DMA_MAR1 0xE50 /* Memory Address Register of Channel 1 */
-#define VIA_PCI_DMA_DAR1 0xE54 /* Device Address Register of Channel 1 */
-#define VIA_PCI_DMA_BCR1 0xE58 /* Byte Count Register of Channel 1 */
-#define VIA_PCI_DMA_DPR1 0xE5C /* Descriptor Pointer Register of Channel 1 */
-
-#define VIA_PCI_DMA_MAR2 0xE60 /* Memory Address Register of Channel 2 */
-#define VIA_PCI_DMA_DAR2 0xE64 /* Device Address Register of Channel 2 */
-#define VIA_PCI_DMA_BCR2 0xE68 /* Byte Count Register of Channel 2 */
-#define VIA_PCI_DMA_DPR2 0xE6C /* Descriptor Pointer Register of Channel 2 */
-
-#define VIA_PCI_DMA_MAR3 0xE70 /* Memory Address Register of Channel 3 */
-#define VIA_PCI_DMA_DAR3 0xE74 /* Device Address Register of Channel 3 */
-#define VIA_PCI_DMA_BCR3 0xE78 /* Byte Count Register of Channel 3 */
-#define VIA_PCI_DMA_DPR3 0xE7C /* Descriptor Pointer Register of Channel 3 */
-
-#define VIA_PCI_DMA_MR0 0xE80 /* Mode Register of Channel 0 */
-#define VIA_PCI_DMA_MR1 0xE84 /* Mode Register of Channel 1 */
-#define VIA_PCI_DMA_MR2 0xE88 /* Mode Register of Channel 2 */
-#define VIA_PCI_DMA_MR3 0xE8C /* Mode Register of Channel 3 */
-
-#define VIA_PCI_DMA_CSR0 0xE90 /* Command/Status Register of Channel 0 */
-#define VIA_PCI_DMA_CSR1 0xE94 /* Command/Status Register of Channel 1 */
-#define VIA_PCI_DMA_CSR2 0xE98 /* Command/Status Register of Channel 2 */
-#define VIA_PCI_DMA_CSR3 0xE9C /* Command/Status Register of Channel 3 */
-
-#define VIA_PCI_DMA_PTR 0xEA0 /* Priority Type Register */
-
-/* Define for DMA engine */
+
+#define VIA_PCI_DMA_MAR0 0xE40 /* Memory Address Register of Channel 0 */
+#define VIA_PCI_DMA_DAR0 0xE44 /* Device Address Register of Channel 0 */
+#define VIA_PCI_DMA_BCR0 0xE48 /* Byte Count Register of Channel 0 */
+#define VIA_PCI_DMA_DPR0 0xE4C /* Descriptor Pointer Register of Channel 0 */
+
+#define VIA_PCI_DMA_MAR1 0xE50 /* Memory Address Register of Channel 1 */
+#define VIA_PCI_DMA_DAR1 0xE54 /* Device Address Register of Channel 1 */
+#define VIA_PCI_DMA_BCR1 0xE58 /* Byte Count Register of Channel 1 */
+#define VIA_PCI_DMA_DPR1 0xE5C /* Descriptor Pointer Register of Channel 1 */
+
+#define VIA_PCI_DMA_MAR2 0xE60 /* Memory Address Register of Channel 2 */
+#define VIA_PCI_DMA_DAR2 0xE64 /* Device Address Register of Channel 2 */
+#define VIA_PCI_DMA_BCR2 0xE68 /* Byte Count Register of Channel 2 */
+#define VIA_PCI_DMA_DPR2 0xE6C /* Descriptor Pointer Register of Channel 2 */
+
+#define VIA_PCI_DMA_MAR3 0xE70 /* Memory Address Register of Channel 3 */
+#define VIA_PCI_DMA_DAR3 0xE74 /* Device Address Register of Channel 3 */
+#define VIA_PCI_DMA_BCR3 0xE78 /* Byte Count Register of Channel 3 */
+#define VIA_PCI_DMA_DPR3 0xE7C /* Descriptor Pointer Register of Channel 3 */
+
+#define VIA_PCI_DMA_MR0 0xE80 /* Mode Register of Channel 0 */
+#define VIA_PCI_DMA_MR1 0xE84 /* Mode Register of Channel 1 */
+#define VIA_PCI_DMA_MR2 0xE88 /* Mode Register of Channel 2 */
+#define VIA_PCI_DMA_MR3 0xE8C /* Mode Register of Channel 3 */
+
+#define VIA_PCI_DMA_CSR0 0xE90 /* Command/Status Register of Channel 0 */
+#define VIA_PCI_DMA_CSR1 0xE94 /* Command/Status Register of Channel 1 */
+#define VIA_PCI_DMA_CSR2 0xE98 /* Command/Status Register of Channel 2 */
+#define VIA_PCI_DMA_CSR3 0xE9C /* Command/Status Register of Channel 3 */
+
+#define VIA_PCI_DMA_PTR 0xEA0 /* Priority Type Register */
+
+/* Define for DMA engine */
/* DPR */
#define VIA_DMA_DPR_EC (1<<1) /* end of chain */
#define VIA_DMA_DPR_DDIE (1<<2) /* descriptor done interrupt enable */
diff --git a/drivers/char/drm/via_drm.h b/drivers/char/drm/via_drm.h
index 8f53c76..a3b5c10 100644
--- a/drivers/char/drm/via_drm.h
+++ b/drivers/char/drm/via_drm.h
@@ -35,7 +35,7 @@
#include "via_drmclient.h"
#endif
-#define VIA_NR_SAREA_CLIPRECTS 8
+#define VIA_NR_SAREA_CLIPRECTS 8
#define VIA_NR_XVMC_PORTS 10
#define VIA_NR_XVMC_LOCKS 5
#define VIA_MAX_CACHELINE_SIZE 64
@@ -259,7 +259,7 @@ typedef struct drm_via_blitsync {
typedef struct drm_via_dmablit {
uint32_t num_lines;
uint32_t line_length;
-
+
uint32_t fb_addr;
uint32_t fb_stride;
diff --git a/drivers/char/drm/via_drv.c b/drivers/char/drm/via_drv.c
index 2d4957a..80c01cd 100644
--- a/drivers/char/drm/via_drv.c
+++ b/drivers/char/drm/via_drv.c
@@ -71,7 +71,7 @@ static struct drm_driver driver = {
.name = DRIVER_NAME,
.id_table = pciidlist,
},
-
+
.name = DRIVER_NAME,
.desc = DRIVER_DESC,
.date = DRIVER_DATE,
diff --git a/drivers/char/drm/via_map.c b/drivers/char/drm/via_map.c
index 1009150..f6dcaaf 100644
--- a/drivers/char/drm/via_map.c
+++ b/drivers/char/drm/via_map.c
@@ -121,4 +121,3 @@ int via_driver_unload(struct drm_device *dev)
return 0;
}
-
diff --git a/drivers/char/drm/via_mm.c b/drivers/char/drm/via_mm.c
index 3ffbf86..69f6558 100644
--- a/drivers/char/drm/via_mm.c
+++ b/drivers/char/drm/via_mm.c
@@ -113,7 +113,7 @@ void via_lastclose(struct drm_device *dev)
dev_priv->vram_initialized = 0;
dev_priv->agp_initialized = 0;
mutex_unlock(&dev->struct_mutex);
-}
+}
int via_mem_alloc(struct drm_device *dev, void *data,
struct drm_file *file_priv)
linux-2.6-drm-radeon-update.patch:
--- NEW FILE linux-2.6-drm-radeon-update.patch ---
diff -up linux-2.6.23.noarch/drivers/char/drm/radeon_drm.h.da linux-2.6.23.noarch/drivers/char/drm/radeon_drm.h
--- linux-2.6.23.noarch/drivers/char/drm/radeon_drm.h.da 2007-10-10 06:31:38.000000000 +1000
+++ linux-2.6.23.noarch/drivers/char/drm/radeon_drm.h 2007-12-12 11:43:08.000000000 +1000
@@ -656,6 +656,7 @@ typedef struct drm_radeon_indirect {
#define RADEON_PARAM_SCRATCH_OFFSET 11
#define RADEON_PARAM_CARD_TYPE 12
#define RADEON_PARAM_VBLANK_CRTC 13 /* VBLANK CRTC */
+#define RADEON_PARAM_FB_LOCATION 14 /* FB location */
typedef struct drm_radeon_getparam {
int param;
diff -up linux-2.6.23.noarch/drivers/char/drm/radeon_state.c.da linux-2.6.23.noarch/drivers/char/drm/radeon_state.c
--- linux-2.6.23.noarch/drivers/char/drm/radeon_state.c.da 2007-12-12 11:42:44.000000000 +1000
+++ linux-2.6.23.noarch/drivers/char/drm/radeon_state.c 2007-12-12 11:43:21.000000000 +1000
@@ -3033,6 +3033,9 @@ static int radeon_cp_getparam(struct drm
case RADEON_PARAM_VBLANK_CRTC:
value = radeon_vblank_crtc_get(dev);
break;
+ case RADEON_PARAM_FB_LOCATION:
+ value = radeon_read_fb_location(dev_priv);
+ break;
default:
DRM_DEBUG("Invalid parameter %d\n", param->param);
return -EINVAL;
diff -up linux-2.6.23.noarch/drivers/char/drm/radeon_cp.c.da linux-2.6.23.noarch/drivers/char/drm/radeon_cp.c
--- linux-2.6.23.noarch/drivers/char/drm/radeon_cp.c.da 2007-12-12 11:42:44.000000000 +1000
+++ linux-2.6.23.noarch/drivers/char/drm/radeon_cp.c 2007-12-12 11:43:08.000000000 +1000
@@ -816,6 +816,21 @@ static const u32 R300_cp_microcode[][2]
{0000000000, 0000000000},
};
+u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv)
+{
+ return RADEON_READ(RADEON_MC_FB_LOCATION);
+}
+
+static void radeon_write_fb_location(drm_radeon_private_t *dev_priv, u32 fb_loc)
+{
+ RADEON_WRITE(RADEON_MC_FB_LOCATION, fb_loc);
+}
+
+static void radeon_write_agp_location(drm_radeon_private_t *dev_priv, u32 agp_loc)
+{
+ RADEON_WRITE(RADEON_MC_AGP_LOCATION, agp_loc);
+}
+
static int RADEON_READ_PLL(struct drm_device * dev, int addr)
{
drm_radeon_private_t *dev_priv = dev->dev_private;
@@ -1134,14 +1149,14 @@ static void radeon_cp_init_ring_buffer(s
* always appended to the fb which is not necessarily the case
*/
if (!dev_priv->new_memmap)
- RADEON_WRITE(RADEON_MC_FB_LOCATION,
+ radeon_write_fb_location(dev_priv,
((dev_priv->gart_vm_start - 1) & 0xffff0000)
| (dev_priv->fb_location >> 16));
#if __OS_HAS_AGP
if (dev_priv->flags & RADEON_IS_AGP) {
RADEON_WRITE(RADEON_AGP_BASE, (unsigned int)dev->agp->base);
- RADEON_WRITE(RADEON_MC_AGP_LOCATION,
+ radeon_write_agp_location(dev_priv,
(((dev_priv->gart_vm_start - 1 +
dev_priv->gart_size) & 0xffff0000) |
(dev_priv->gart_vm_start >> 16)));
@@ -1299,7 +1314,7 @@ static void radeon_set_igpgart(drm_radeo
RADEON_WRITE(RADEON_AGP_BASE, (unsigned int)dev_priv->gart_vm_start);
dev_priv->gart_size = 32*1024*1024;
- RADEON_WRITE(RADEON_MC_AGP_LOCATION,
+ radeon_write_agp_location(dev_priv,
(((dev_priv->gart_vm_start - 1 +
dev_priv->gart_size) & 0xffff0000) |
(dev_priv->gart_vm_start >> 16)));
@@ -1333,7 +1348,7 @@ static void radeon_set_pciegart(drm_rade
dev_priv->gart_vm_start +
dev_priv->gart_size - 1);
- RADEON_WRITE(RADEON_MC_AGP_LOCATION, 0xffffffc0); /* ?? */
+ radeon_write_agp_location(dev_priv, 0xffffffc0); /* ?? */
RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_CNTL,
RADEON_PCIE_TX_GART_EN);
@@ -1376,7 +1391,7 @@ static void radeon_set_pcigart(drm_radeo
/* Turn off AGP aperture -- is this required for PCI GART?
*/
- RADEON_WRITE(RADEON_MC_AGP_LOCATION, 0xffffffc0); /* ?? */
+ radeon_write_agp_location(dev_priv, 0xffffffc0);
RADEON_WRITE(RADEON_AGP_COMMAND, 0); /* clear AGP_COMMAND */
} else {
RADEON_WRITE(RADEON_AIC_CNTL,
@@ -1581,10 +1596,9 @@ static int radeon_do_init_cp(struct drm_
dev->agp_buffer_map->handle);
}
- dev_priv->fb_location = (RADEON_READ(RADEON_MC_FB_LOCATION)
- & 0xffff) << 16;
+ dev_priv->fb_location = (radeon_read_fb_location(dev_priv) & 0xffff) << 16;
dev_priv->fb_size =
- ((RADEON_READ(RADEON_MC_FB_LOCATION) & 0xffff0000u) + 0x10000)
+ ((radeon_read_fb_location(dev_priv) & 0xffff0000u) + 0x10000)
- dev_priv->fb_location;
dev_priv->front_pitch_offset = (((dev_priv->front_pitch / 64) << 22) |
diff -up linux-2.6.23.noarch/drivers/char/drm/radeon_drv.h.da linux-2.6.23.noarch/drivers/char/drm/radeon_drv.h
--- linux-2.6.23.noarch/drivers/char/drm/radeon_drv.h.da 2007-12-12 11:42:44.000000000 +1000
+++ linux-2.6.23.noarch/drivers/char/drm/radeon_drv.h 2007-12-12 11:43:08.000000000 +1000
@@ -336,6 +336,7 @@ extern int radeon_cp_resume(struct drm_d
extern int radeon_engine_reset(struct drm_device *dev, void *data, struct drm_file *file_priv);
extern int radeon_fullscreen(struct drm_device *dev, void *data, struct drm_file *file_priv);
extern int radeon_cp_buffers(struct drm_device *dev, void *data, struct drm_file *file_priv);
+extern u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv);
extern void radeon_freelist_reset(struct drm_device * dev);
extern struct drm_buf *radeon_freelist_get(struct drm_device * dev);
linux-2.6-e1000-corrupt-eeprom-checksum.patch:
--- NEW FILE linux-2.6-e1000-corrupt-eeprom-checksum.patch ---
diff -up linux-2.6.23.noarch/drivers/net/e1000/e1000_main.c.jx vanilla/drivers/net/e1000/e1000_main.c
--- linux-2.6.23.noarch/drivers/net/e1000/e1000_main.c.jx 2007-10-09 16:31:38.000000000 -0400
+++ linux-2.6.23.noarch/drivers/net/e1000/e1000_main.c 2007-10-22 16:33:01.000000000 -0400
@@ -255,6 +255,10 @@ static int debug = NETIF_MSG_DRV | NETIF
module_param(debug, int, 0);
MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
+static int eeprom_bad_csum_allow = 0;
+module_param(eeprom_bad_csum_allow, int, 0);
+MODULE_PARM_DESC(eeprom_bad_csum_allow, "Allow bad eeprom checksums");
+
/**
* e1000_init_module - Driver Registration Routine
*
@@ -1012,7 +1016,8 @@ e1000_probe(struct pci_dev *pdev,
if (e1000_validate_eeprom_checksum(&adapter->hw) < 0) {
DPRINTK(PROBE, ERR, "The EEPROM Checksum Is Not Valid\n");
- goto err_eeprom;
+ if (!eeprom_bad_csum_allow)
+ goto err_eeprom;
}
/* copy the MAC address out of the EEPROM */
@@ -1024,7 +1029,8 @@ e1000_probe(struct pci_dev *pdev,
if (!is_valid_ether_addr(netdev->perm_addr)) {
DPRINTK(PROBE, ERR, "Invalid MAC Address\n");
- goto err_eeprom;
+ if (!eeprom_bad_csum_allow)
+ goto err_eeprom;
}
e1000_get_bus_info(&adapter->hw);
linux-2.6-epoll-lockdep-annotation.patch:
--- NEW FILE linux-2.6-epoll-lockdep-annotation.patch ---
Index: linux-2.6/fs/eventpoll.c
===================================================================
--- linux-2.6.orig/fs/eventpoll.c
+++ linux-2.6/fs/eventpoll.c
@@ -353,7 +353,7 @@ static void ep_poll_safewake(struct poll
spin_unlock_irqrestore(&psw->lock, flags);
/* Do really wake up now */
- wake_up(wq);
+ wake_up_nested(wq, 1 + wake_nests);
/* Remove the current task from the list */
spin_lock_irqsave(&psw->lock, flags);
Index: linux-2.6/include/linux/wait.h
===================================================================
--- linux-2.6.orig/include/linux/wait.h
+++ linux-2.6/include/linux/wait.h
@@ -161,6 +161,22 @@ wait_queue_head_t *FASTCALL(bit_waitqueu
#define wake_up_locked(x) __wake_up_locked((x), TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE)
#define wake_up_interruptible_sync(x) __wake_up_sync((x),TASK_INTERRUPTIBLE, 1)
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+/*
+ * macro to avoid include hell
+ */
+#define wake_up_nested(x, s) \
+do { \
+ unsigned long flags; \
+ \
+ spin_lock_irqsave_nested(&(x)->lock, flags, (s)); \
+ wake_up_locked(x); \
+ spin_unlock_irqrestore(&(x)->lock, flags); \
+} while (0)
+#else
+#define wake_up_nested(x, s) wake_up(x)
+#endif
+
#define __wait_event(wq, condition) \
do { \
DEFINE_WAIT(__wait); \
linux-2.6-ext4-linus-git.patch:
--- NEW FILE linux-2.6-ext4-linus-git.patch ---
ext4/jbd2/support changes from 2.6.24-git13
--- a/Documentation/filesystems/ext4.txt
+++ b/Documentation/filesystems/ext4.txt
@@ -86,9 +86,21 @@ Alex is working on a new set of patches right now.
When mounting an ext4 filesystem, the following option are accepted:
(*) == default
-extents ext4 will use extents to address file data. The
+extents (*) ext4 will use extents to address file data. The
file system will no longer be mountable by ext3.
+noextents ext4 will not use extents for newly created files
+
+journal_checksum Enable checksumming of the journal transactions.
+ This will allow the recovery code in e2fsck and the
+ kernel to detect corruption in the kernel. It is a
+ compatible change and will be ignored by older kernels.
+
+journal_async_commit Commit block can be written to disk without waiting
+ for descriptor blocks. If enabled older kernels cannot
+ mount the device. This will enable 'journal_checksum'
+ internally.
+
journal=update Update the ext4 file system's journal to the current
format.
@@ -196,6 +208,12 @@ nobh (a) cache disk block mapping information
"nobh" option tries to avoid associating buffer
heads (supported only for "writeback" mode).
+mballoc (*) Use the multiple block allocator for block allocation
+nomballoc disabled multiple block allocator for block allocation.
+stripe=n Number of filesystem blocks that mballoc will try
+ to use for allocation size and alignment. For RAID5/6
+ systems this should be the number of data
+ disks * RAID chunk size in file system blocks.
Data Mode
---------
--- a/Documentation/filesystems/proc.txt
+++ b/Documentation/filesystems/proc.txt
@@ -857,6 +857,45 @@ CPUs.
The "procs_blocked" line gives the number of processes currently blocked,
waiting for I/O to complete.
+1.9 Ext4 file system parameters
+------------------------------
+Ext4 file system have one directory per partition under /proc/fs/ext4/
+# ls /proc/fs/ext4/hdc/
+group_prealloc max_to_scan mb_groups mb_history min_to_scan order2_req
+stats stream_req
+
+mb_groups:
+This file gives the details of mutiblock allocator buddy cache of free blocks
+
+mb_history:
+Multiblock allocation history.
+
+stats:
+This file indicate whether the multiblock allocator should start collecting
+statistics. The statistics are shown during unmount
+
+group_prealloc:
+The multiblock allocator normalize the block allocation request to
+group_prealloc filesystem blocks if we don't have strip value set.
+The stripe value can be specified at mount time or during mke2fs.
+
+max_to_scan:
+How long multiblock allocator can look for a best extent (in found extents)
+
+min_to_scan:
+How long multiblock allocator must look for a best extent
+
+order2_req:
+Multiblock allocator use 2^N search using buddies only for requests greater
+than or equal to order2_req. The request size is specfied in file system
+blocks. A value of 2 indicate only if the requests are greater than or equal
+to 4 blocks.
+
+stream_req:
+Files smaller than stream_req are served by the stream allocator, whose
+purpose is to pack requests as close each to other as possible to
+produce smooth I/O traffic. Avalue of 16 indicate that file smaller than 16
+filesystem block size will use group based preallocation.
------------------------------------------------------------------------------
Summary
--- a/fs/afs/dir.c
+++ b/fs/afs/dir.c
@@ -546,11 +546,11 @@ static struct dentry *afs_lookup(struct inode *dir, struct dentry *dentry,
dentry->d_op = &afs_fs_dentry_operations;
d_add(dentry, inode);
- _leave(" = 0 { vn=%u u=%u } -> { ino=%lu v=%lu }",
+ _leave(" = 0 { vn=%u u=%u } -> { ino=%lu v=%llu }",
fid.vnode,
fid.unique,
dentry->d_inode->i_ino,
- dentry->d_inode->i_version);
+ (unsigned long long)dentry->d_inode->i_version);
return NULL;
}
@@ -630,9 +630,10 @@ static int afs_d_revalidate(struct dentry *dentry, struct nameidata *nd)
* been deleted and replaced, and the original vnode ID has
* been reused */
if (fid.unique != vnode->fid.unique) {
- _debug("%s: file deleted (uq %u -> %u I:%lu)",
+ _debug("%s: file deleted (uq %u -> %u I:%llu)",
dentry->d_name.name, fid.unique,
- vnode->fid.unique, dentry->d_inode->i_version);
+ vnode->fid.unique,
+ (unsigned long long)dentry->d_inode->i_version);
spin_lock(&vnode->lock);
set_bit(AFS_VNODE_DELETED, &vnode->flags);
spin_unlock(&vnode->lock);
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -3213,6 +3213,50 @@ static int buffer_cpu_notify(struct notifier_block *self,
return NOTIFY_OK;
}
+/**
+ * bh_uptodate_or_lock: Test whether the buffer is uptodate
+ * @bh: struct buffer_head
+ *
+ * Return true if the buffer is up-to-date and false,
+ * with the buffer locked, if not.
+ */
+int bh_uptodate_or_lock(struct buffer_head *bh)
+{
+ if (!buffer_uptodate(bh)) {
+ lock_buffer(bh);
+ if (!buffer_uptodate(bh))
+ return 0;
+ unlock_buffer(bh);
+ }
+ return 1;
+}
+EXPORT_SYMBOL(bh_uptodate_or_lock);
+
+/**
+ * bh_submit_read: Submit a locked buffer for reading
+ * @bh: struct buffer_head
+ *
+ * Returns zero on success and -EIO on error.
+ */
+int bh_submit_read(struct buffer_head *bh)
+{
+ BUG_ON(!buffer_locked(bh));
+
+ if (buffer_uptodate(bh)) {
+ unlock_buffer(bh);
+ return 0;
+ }
+
+ get_bh(bh);
+ bh->b_end_io = end_buffer_read_sync;
+ submit_bh(READ, bh);
+ wait_on_buffer(bh);
+ if (buffer_uptodate(bh))
+ return 0;
+ return -EIO;
+}
+EXPORT_SYMBOL(bh_submit_read);
+
void __init buffer_init(void)
{
int nrpages;
--- a/fs/ext4/balloc.c
+++ b/fs/ext4/balloc.c
@@ -29,7 +29,7 @@
* Calculate the block group number and offset, given a block number
*/
void ext4_get_group_no_and_offset(struct super_block *sb, ext4_fsblk_t blocknr,
- unsigned long *blockgrpp, ext4_grpblk_t *offsetp)
+ ext4_group_t *blockgrpp, ext4_grpblk_t *offsetp)
{
struct ext4_super_block *es = EXT4_SB(sb)->s_es;
ext4_grpblk_t offset;
@@ -46,7 +46,7 @@ void ext4_get_group_no_and_offset(struct super_block *sb, ext4_fsblk_t blocknr,
/* Initializes an uninitialized block bitmap if given, and returns the
* number of blocks free in the group. */
unsigned ext4_init_block_bitmap(struct super_block *sb, struct buffer_head *bh,
- int block_group, struct ext4_group_desc *gdp)
+ ext4_group_t block_group, struct ext4_group_desc *gdp)
{
unsigned long start;
int bit, bit_max;
@@ -60,7 +60,7 @@ unsigned ext4_init_block_bitmap(struct super_block *sb, struct buffer_head *bh,
* essentially implementing a per-group read-only flag. */
if (!ext4_group_desc_csum_verify(sbi, block_group, gdp)) {
ext4_error(sb, __FUNCTION__,
- "Checksum bad for group %u\n", block_group);
+ "Checksum bad for group %lu\n", block_group);
gdp->bg_free_blocks_count = 0;
gdp->bg_free_inodes_count = 0;
gdp->bg_itable_unused = 0;
[...11186 lines suppressed...]
#if defined(CONFIG_BUFFER_DEBUG)
void buffer_assertion_failure(struct buffer_head *bh);
@@ -282,10 +298,6 @@ void buffer_assertion_failure(struct buffer_head *bh);
#define J_ASSERT_JH(jh, expr) J_ASSERT(expr)
#endif
-#else
-#define J_ASSERT(assert) do { } while (0)
-#endif /* JBD2_ASSERTIONS */
-
#if defined(JBD2_PARANOID_IOFAIL)
#define J_EXPECT(expr, why...) J_ASSERT(expr)
#define J_EXPECT_BH(bh, expr, why...) J_ASSERT_BH(bh, expr)
@@ -406,9 +418,23 @@ struct handle_s
unsigned int h_sync: 1; /* sync-on-close */
unsigned int h_jdata: 1; /* force data journaling */
unsigned int h_aborted: 1; /* fatal error on handle */
+
+#ifdef CONFIG_DEBUG_LOCK_ALLOC
+ struct lockdep_map h_lockdep_map;
+#endif
};
+/*
+ * Some stats for checkpoint phase
+ */
+struct transaction_chp_stats_s {
+ unsigned long cs_chp_time;
+ unsigned long cs_forced_to_close;
+ unsigned long cs_written;
+ unsigned long cs_dropped;
+};
+
/* The transaction_t type is the guts of the journaling mechanism. It
* tracks a compound transaction through its various states:
*
@@ -456,6 +482,8 @@ struct transaction_s
/*
* Transaction's current state
* [no locking - only kjournald2 alters this]
+ * [j_list_lock] guards transition of a transaction into T_FINISHED
+ * state and subsequent call of __jbd2_journal_drop_transaction()
* FIXME: needs barriers
* KLUDGE: [use j_state_lock]
*/
@@ -544,6 +572,21 @@ struct transaction_s
spinlock_t t_handle_lock;
/*
+ * Longest time some handle had to wait for running transaction
+ */
+ unsigned long t_max_wait;
+
+ /*
+ * When transaction started
+ */
+ unsigned long t_start;
+
+ /*
+ * Checkpointing stats [j_checkpoint_sem]
+ */
+ struct transaction_chp_stats_s t_chp_stats;
+
+ /*
* Number of outstanding updates running on this transaction
* [t_handle_lock]
*/
@@ -574,6 +617,39 @@ struct transaction_s
};
+struct transaction_run_stats_s {
+ unsigned long rs_wait;
+ unsigned long rs_running;
+ unsigned long rs_locked;
+ unsigned long rs_flushing;
+ unsigned long rs_logging;
+
+ unsigned long rs_handle_count;
+ unsigned long rs_blocks;
+ unsigned long rs_blocks_logged;
+};
+
+struct transaction_stats_s {
+ int ts_type;
+ unsigned long ts_tid;
+ union {
+ struct transaction_run_stats_s run;
+ struct transaction_chp_stats_s chp;
+ } u;
+};
+
+#define JBD2_STATS_RUN 1
+#define JBD2_STATS_CHECKPOINT 2
+
+static inline unsigned long
+jbd2_time_diff(unsigned long start, unsigned long end)
+{
+ if (end >= start)
+ return end - start;
+
+ return end + (MAX_JIFFY_OFFSET - start);
+}
+
/**
* struct journal_s - The journal_s type is the concrete type associated with
* journal_t.
@@ -635,6 +711,12 @@ struct transaction_s
* @j_wbufsize: maximum number of buffer_heads allowed in j_wbuf, the
* number that will fit in j_blocksize
* @j_last_sync_writer: most recent pid which did a synchronous write
+ * @j_history: Buffer storing the transactions statistics history
+ * @j_history_max: Maximum number of transactions in the statistics history
+ * @j_history_cur: Current number of transactions in the statistics history
+ * @j_history_lock: Protect the transactions statistics history
+ * @j_proc_entry: procfs entry for the jbd statistics directory
+ * @j_stats: Overall statistics
* @j_private: An opaque pointer to fs-private information.
*/
@@ -827,6 +909,19 @@ struct journal_s
pid_t j_last_sync_writer;
/*
+ * Journal statistics
+ */
+ struct transaction_stats_s *j_history;
+ int j_history_max;
+ int j_history_cur;
+ /*
+ * Protect the transactions statistics history
+ */
+ spinlock_t j_history_lock;
+ struct proc_dir_entry *j_proc_entry;
+ struct transaction_stats_s j_stats;
+
+ /*
* An opaque pointer to fs-private information. ext3 puts its
* superblock pointer here
*/
@@ -932,6 +1027,8 @@ extern int jbd2_journal_check_available_features
(journal_t *, unsigned long, unsigned long, unsigned long);
extern int jbd2_journal_set_features
(journal_t *, unsigned long, unsigned long, unsigned long);
+extern void jbd2_journal_clear_features
+ (journal_t *, unsigned long, unsigned long, unsigned long);
extern int jbd2_journal_create (journal_t *);
extern int jbd2_journal_load (journal_t *journal);
extern void jbd2_journal_destroy (journal_t *);
--- a/lib/find_next_bit.c
+++ b/lib/find_next_bit.c
@@ -178,4 +178,47 @@ found_middle_swap:
EXPORT_SYMBOL(generic_find_next_zero_le_bit);
+unsigned long generic_find_next_le_bit(const unsigned long *addr, unsigned
+ long size, unsigned long offset)
+{
+ const unsigned long *p = addr + BITOP_WORD(offset);
+ unsigned long result = offset & ~(BITS_PER_LONG - 1);
+ unsigned long tmp;
+
+ if (offset >= size)
+ return size;
+ size -= result;
+ offset &= (BITS_PER_LONG - 1UL);
+ if (offset) {
+ tmp = ext2_swabp(p++);
+ tmp &= (~0UL << offset);
+ if (size < BITS_PER_LONG)
+ goto found_first;
+ if (tmp)
+ goto found_middle;
+ size -= BITS_PER_LONG;
+ result += BITS_PER_LONG;
+ }
+
+ while (size & ~(BITS_PER_LONG - 1)) {
+ tmp = *(p++);
+ if (tmp)
+ goto found_middle_swap;
+ result += BITS_PER_LONG;
+ size -= BITS_PER_LONG;
+ }
+ if (!size)
+ return result;
+ tmp = ext2_swabp(p);
+found_first:
+ tmp &= (~0UL >> (BITS_PER_LONG - size));
+ if (tmp == 0UL) /* Are any bits set? */
+ return result + size; /* Nope. */
+found_middle:
+ return result + __ffs(tmp);
+
+found_middle_swap:
+ return result + __ffs(ext2_swab(tmp));
+}
+EXPORT_SYMBOL(generic_find_next_le_bit);
#endif /* __BIG_ENDIAN */
linux-2.6-ext4-stable-queue.patch:
--- NEW FILE linux-2.6-ext4-stable-queue.patch ---
Patches from ext4 stable patch queue not yet in git.
As of 04 Feb 2008:
jbd2_journal_chksum_null_pointer_fix.patch
jbd2_fix_ref_count_on_bh.patch
jbd2_use_incompat_macro_to_check_JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT.patch
ext4_do_not_set_EXTENTS_FL_for_fast_symlinks.patch
test-filesys-flag.patch
allow_in-inode_eas_on_ext4_root_inode
===================================
JBD2: Fix null pointer deference in jbd2 journal checksum code
From: Mingming Cao <cmm u ibm com>
The buffer head pointer passed to journal_wait_on_commit_record()
could be NULL if the previous journal_submit_commit_record() failed
or journal has already aborted.
We need to check the error returns from journal_submit_commit_record()
and avoid calling journal_wait_on_commit_record() in the failure case.
Signed-off-by: Mingming Cao <cmm us ibm com>
---
fs/jbd2/commit.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
Index: linux-2.6.24/fs/jbd2/commit.c
===================================================================
--- linux-2.6.24.orig/fs/jbd2/commit.c 2008-02-04 11:02:42.000000000 -0800
+++ linux-2.6.24/fs/jbd2/commit.c 2008-02-04 11:18:43.000000000 -0800
@@ -865,7 +865,8 @@ wait_for_iobuf:
if (err)
__jbd2_journal_abort_hard(journal);
}
- err = journal_wait_on_commit_record(cbh);
+ if (!err && !is_journal_aborted(journal))
+ err = journal_wait_on_commit_record(cbh);
if (err)
jbd2_journal_abort(journal, err);
JBD2: Fix reference counting on buffer head.
From: "Aneesh Kumar K.V" <aneesh kumar linux vnet ibm com>
With journal checksum patch we added asyn commit of journal commit headers.
During the conversion we missed to take a reference on buffer head. Before
the change sync_dirty_buffer did the get_bh(). The associative put_bh is
done by journal_wait_on_commit_record()
Signed-off-by: Aneesh Kumar K.V <aneesh kumar linux vnet ibm com>
Signed-off-by: Mingming Cao <cmm us ibm com>
---
fs/jbd2/commit.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Index: linux-2.6.24/fs/jbd2/commit.c
===================================================================
--- linux-2.6.24.orig/fs/jbd2/commit.c 2008-02-04 11:02:43.000000000 -0800
+++ linux-2.6.24/fs/jbd2/commit.c 2008-02-04 11:18:39.000000000 -0800
@@ -136,7 +136,7 @@ static int journal_submit_commit_record(
JBUFFER_TRACE(descriptor, "submit commit block");
lock_buffer(bh);
-
+ get_bh(bh);
set_buffer_dirty(bh);
set_buffer_uptodate(bh);
bh->b_end_io = journal_end_buffer_io_sync;
JBD2: Use the incompat macro for testing the incompat feature.
From: "Aneesh Kumar K.V" <aneesh kumar linux vnet ibm com>
JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT need to be checked with JBD2_HAS_INCOMPAT_FEATURE
Signed-off-by: Aneesh Kumar K.V <aneesh kumar linux vnet ibm com>
Signed-off