summaryrefslogtreecommitdiffstats
path: root/meta-moblin/packages/linux
diff options
context:
space:
mode:
authorSamuel Ortiz <sameo@linux.intel.com>2008-10-21 16:25:42 +0200
committerSamuel Ortiz <sameo@openedhand.com>2008-10-21 16:26:53 +0200
commite169b23e66575856c5712b8f2162e305d8560d6b (patch)
tree44b2549bfc20563c79808b92db16baf7101adda1 /meta-moblin/packages/linux
parente5c53ce035eb36fc1b416e9971582a45754844be (diff)
downloadpoky-e169b23e66575856c5712b8f2162e305d8560d6b.tar.gz
linux-moblin: Add 2.6.27 moblin kernel
This will be the default moblin kernel. We also moved the 2.6.27-rc* kernels to meta-moblin.
Diffstat (limited to 'meta-moblin/packages/linux')
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27-rc1/0001_Export_shmem_file_setup_for_DRM-GEM.patch27
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27-rc1/0002_i915.Use_more_consistent_names_for_regs.patch2739
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27-rc1/0003_i915.Add_support_for_MSI_and_interrupt_mitigation.patch421
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27-rc1/0004_i915.Track_progress_inside_of_batchbuffers_for_determining_wedgedness.patch47
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27-rc1/0005_i915.remove_settable_use_mi_batchbuffer_start.patch59
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27-rc1/0006_i915.Ignore_X_server_provided_mmio_address.patch42
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27-rc1/0007_i915.Initialize_hardware_status_page_at_device_load_when_possible.patch138
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27-rc1/0008_drm.Add_GEM_graphics_execution_manager_to_i915_driver.patch5453
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27-rc1/0009-squashfs3.3-2.6.27.patch6727
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27-rc1/0010_unionfs-2.4_for_2.6.27-rc1.patch11320
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27-rc1/0011_workaround_unidef_step.patch10
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27-rc1/0012_intelfb_945gme.patch153
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27-rc1/defconfig-eee9012419
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27-rc1/defconfig-netbook2419
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0001-drm-remove-define-for-non-linux-systems.patch48
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0002-i915-remove-settable-use_mi_batchbuffer_start.patch60
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0003-i915-Ignore-X-server-provided-mmio-address.patch41
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0004-i915-Use-more-consistent-names-for-regs-and-store.patch2746
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0005-i915-Add-support-for-MSI-and-interrupt-mitigation.patch424
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0006-i915-Track-progress-inside-of-batchbuffers-for-dete.patch46
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0007-i915-Initialize-hardware-status-page-at-device-load.patch137
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0008-Add-Intel-ACPI-IGD-OpRegion-support.patch572
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0009-drm-fix-sysfs-error-path.patch23
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0010-i915-separate-suspend-resume-functions.patch1079
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0011-drm-vblank-rework.patch1534
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0012-Export-shmem_file_setup-for-DRM-GEM.patch25
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0013-Export-kmap_atomic_pfn-for-DRM-GEM.patch24
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0014-drm-Add-GEM-graphics-execution-manager-to-i915.patch5483
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0015-i915-Add-chip-set-ID-param.patch35
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0016-i915-Use-struct_mutex-to-protect-ring-in-GEM-mode.patch205
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0017-i915-Make-use-of-sarea_priv-conditional.patch147
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0018-i915-gem-install-and-uninstall-irq-handler-in-enter.patch44
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0019-DRM-Return-EBADF-on-bad-object-in-flink-and-retur.patch32
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0020-drm-Avoid-oops-in-GEM-execbuffers-with-bad-argument.patch23
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0021-drm-G33-class-hardware-has-a-newer-965-style-MCH-n.patch23
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0022-drm-use-ioremap_wc-in-i915-instead-of-ioremap.patch58
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0023-drm-clean-up-many-sparse-warnings-in-i915.patch192
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0024-fastboot-create-a-asynchronous-initlevel.patch136
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0025-fastboot-turn-the-USB-hostcontroller-initcalls-into.patch62
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0026-fastboot-convert-a-few-non-critical-ACPI-drivers-to.patch54
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0027-fastboot-hold-the-BKL-over-the-async-init-call-sequ.patch40
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0028-fastboot-sync-the-async-execution-before-late_initc.patch95
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0029-fastboot-make-fastboot-a-config-option.patch56
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0030-fastboot-retry-mounting-the-root-fs-if-we-can-t-fin.patch67
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0031-fastboot-make-the-raid-autodetect-code-wait-for-all.patch41
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0032-fastboot-remove-wait-for-all-devices-before-mounti.patch44
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0033-fastboot-make-the-RAID-autostart-code-print-a-messa.patch32
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0034-fastboot-fix-typo-in-init-Kconfig-text.patch29
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0035-fastboot-remove-duplicate-unpack_to_rootfs.patch161
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0036-warning-fix-init-do_mounts_md-c.patch82
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0037-init-initramfs.c-unused-function-when-compiling-wit.patch37
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0038-fastboot-fix-blackfin-breakage-due-to-vmlinux.lds-c.patch38
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0039-Add-a-script-to-visualize-the-kernel-boot-process.patch183
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0040-fastboot-fix-issues-and-improve-output-of-bootgraph.patch91
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0041-r8169-8101e.patch940
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0042-intelfb-945gme.patch153
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/defconfig-eee9012424
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/defconfig-netbook2424
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27/0001-drm-remove-define-for-non-linux-systems.patch48
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27/0002-i915-remove-settable-use_mi_batchbuffer_start.patch60
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27/0003-i915-Ignore-X-server-provided-mmio-address.patch41
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27/0004-i915-Use-more-consistent-names-for-regs-and-store.patch2746
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27/0005-i915-Add-support-for-MSI-and-interrupt-mitigation.patch424
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27/0006-i915-Track-progress-inside-of-batchbuffers-for-dete.patch46
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27/0007-i915-Initialize-hardware-status-page-at-device-load.patch137
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27/0008-Add-Intel-ACPI-IGD-OpRegion-support.patch572
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27/0009-drm-fix-sysfs-error-path.patch23
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27/0010-i915-separate-suspend-resume-functions.patch1079
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27/0011-drm-vblank-rework.patch1534
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27/0012-Export-shmem_file_setup-for-DRM-GEM.patch25
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27/0013-Export-kmap_atomic_pfn-for-DRM-GEM.patch24
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27/0014-drm-Add-GEM-graphics-execution-manager-to-i915.patch5483
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27/0015-i915-Add-chip-set-ID-param.patch35
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27/0016-i915-Use-struct_mutex-to-protect-ring-in-GEM-mode.patch205
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27/0017-i915-Make-use-of-sarea_priv-conditional.patch147
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27/0018-i915-gem-install-and-uninstall-irq-handler-in-enter.patch44
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27/0019-DRM-Return-EBADF-on-bad-object-in-flink-and-retur.patch32
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27/0020-drm-Avoid-oops-in-GEM-execbuffers-with-bad-argument.patch23
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27/0021-drm-G33-class-hardware-has-a-newer-965-style-MCH-n.patch23
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27/0022-drm-use-ioremap_wc-in-i915-instead-of-ioremap.patch58
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27/0023-drm-clean-up-many-sparse-warnings-in-i915.patch192
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27/0024-fastboot-create-a-asynchronous-initlevel.patch133
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27/0025-fastboot-turn-the-USB-hostcontroller-initcalls-into.patch59
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27/0026-fastboot-convert-a-few-non-critical-ACPI-drivers-to.patch51
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27/0027-fastboot-hold-the-BKL-over-the-async-init-call-sequ.patch37
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27/0028-fastboot-sync-the-async-execution-before-late_initc.patch92
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27/0029-fastboot-make-fastboot-a-config-option.patch53
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27/0030-fastboot-retry-mounting-the-root-fs-if-we-can-t-fin.patch64
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27/0031-fastboot-make-the-raid-autodetect-code-wait-for-all.patch41
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27/0032-fastboot-remove-wait-for-all-devices-before-mounti.patch41
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27/0033-fastboot-make-the-RAID-autostart-code-print-a-messa.patch32
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27/0034-fastboot-fix-typo-in-init-Kconfig-text.patch26
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27/0035-fastboot-remove-duplicate-unpack_to_rootfs.patch161
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27/0036-warning-fix-init-do_mounts_md-c.patch82
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27/0037-init-initramfs.c-unused-function-when-compiling-wit.patch37
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27/0038-fastboot-fix-blackfin-breakage-due-to-vmlinux.lds-c.patch38
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27/0039-Add-a-script-to-visualize-the-kernel-boot-process.patch177
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27/0040-fastboot-fix-issues-and-improve-output-of-bootgraph.patch91
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27/0041-r8169-8101e.patch940
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27/0042-intelfb-945gme.patch154
-rw-r--r--meta-moblin/packages/linux/linux-moblin-2.6.27/defconfig-netbook2406
-rw-r--r--meta-moblin/packages/linux/linux-moblin.inc18
-rw-r--r--meta-moblin/packages/linux/linux-moblin_2.6.27-rc1.bb21
-rw-r--r--meta-moblin/packages/linux/linux-moblin_2.6.27-rc6.bb54
-rw-r--r--meta-moblin/packages/linux/linux-moblin_2.6.27.bb54
105 files changed, 70027 insertions, 0 deletions
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27-rc1/0001_Export_shmem_file_setup_for_DRM-GEM.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc1/0001_Export_shmem_file_setup_for_DRM-GEM.patch
new file mode 100644
index 0000000000..9589838afa
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc1/0001_Export_shmem_file_setup_for_DRM-GEM.patch
@@ -0,0 +1,27 @@
1From: Keith Packard <keithp@keithp.com>
2Date: Fri, 20 Jun 2008 07:08:06 +0000 (-0700)
3Subject: Export shmem_file_setup for DRM-GEM
4X-Git-Tag: v2.6.12-rc2
5X-Git-Url: http://gitweb.freedesktop.org/?p=users/anholt/anholt/linux-2.6.git;a=commitdiff;h=350ea3ece12744ae154bbc2ea13da6ba84ca5515
6
7Export shmem_file_setup for DRM-GEM
8
9GEM needs to create shmem files to back buffer objects. Though currently
10creation of files for objects could have been driven from userland, the
11modesetting work will require allocation of buffer objects before userland
12is running, for boot-time message display.
13
14Signed-off-by: Eric Anholt <eric@anholt.net>
15---
16
17--- a/mm/shmem.c
18+++ b/mm/shmem.c
19@@ -2582,6 +2582,7 @@ put_memory:
20 shmem_unacct_size(flags, size);
21 return ERR_PTR(error);
22 }
23+EXPORT_SYMBOL(shmem_file_setup);
24
25 /**
26 * shmem_zero_setup - setup a shared anonymous mapping
27
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27-rc1/0002_i915.Use_more_consistent_names_for_regs.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc1/0002_i915.Use_more_consistent_names_for_regs.patch
new file mode 100644
index 0000000000..9a035b544c
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc1/0002_i915.Use_more_consistent_names_for_regs.patch
@@ -0,0 +1,2739 @@
1From: Jesse Barnes <jbarnes@virtuousgeek.org>
2Date: Tue, 29 Jul 2008 18:54:06 +0000 (-0700)
3Subject: i915: Use more consistent names for regs, and store them in a separate file.
4X-Git-Tag: v2.6.12-rc2
5X-Git-Url: http://gitweb.freedesktop.org/?p=users/anholt/anholt/linux-2.6.git;a=commitdiff;h=db1cbbd8c4d42e58e9acb3e7af59ad1bb238260d
6
7i915: Use more consistent names for regs, and store them in a separate file.
8
9Signed-off-by: Eric Anholt <eric@anholt.net>
10---
11
12--- a/drivers/gpu/drm/i915/i915_dma.c
13+++ b/drivers/gpu/drm/i915/i915_dma.c
14@@ -40,11 +40,11 @@ int i915_wait_ring(struct drm_device * d
15 {
16 drm_i915_private_t *dev_priv = dev->dev_private;
17 drm_i915_ring_buffer_t *ring = &(dev_priv->ring);
18- u32 last_head = I915_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
19+ u32 last_head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
20 int i;
21
22 for (i = 0; i < 10000; i++) {
23- ring->head = I915_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
24+ ring->head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
25 ring->space = ring->head - (ring->tail + 8);
26 if (ring->space < 0)
27 ring->space += ring->Size;
28@@ -67,8 +67,8 @@ void i915_kernel_lost_context(struct drm
29 drm_i915_private_t *dev_priv = dev->dev_private;
30 drm_i915_ring_buffer_t *ring = &(dev_priv->ring);
31
32- ring->head = I915_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
33- ring->tail = I915_READ(LP_RING + RING_TAIL) & TAIL_ADDR;
34+ ring->head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
35+ ring->tail = I915_READ(PRB0_TAIL) & TAIL_ADDR;
36 ring->space = ring->head - (ring->tail + 8);
37 if (ring->space < 0)
38 ring->space += ring->Size;
39@@ -98,13 +98,13 @@ static int i915_dma_cleanup(struct drm_d
40 drm_pci_free(dev, dev_priv->status_page_dmah);
41 dev_priv->status_page_dmah = NULL;
42 /* Need to rewrite hardware status page */
43- I915_WRITE(0x02080, 0x1ffff000);
44+ I915_WRITE(HWS_PGA, 0x1ffff000);
45 }
46
47 if (dev_priv->status_gfx_addr) {
48 dev_priv->status_gfx_addr = 0;
49 drm_core_ioremapfree(&dev_priv->hws_map, dev);
50- I915_WRITE(0x2080, 0x1ffff000);
51+ I915_WRITE(HWS_PGA, 0x1ffff000);
52 }
53
54 return 0;
55@@ -170,7 +170,7 @@ static int i915_initialize(struct drm_de
56 dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr;
57
58 memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
59- I915_WRITE(0x02080, dev_priv->dma_status_page);
60+ I915_WRITE(HWS_PGA, dev_priv->dma_status_page);
61 }
62 DRM_DEBUG("Enabled hardware status page\n");
63 return 0;
64@@ -201,9 +201,9 @@ static int i915_dma_resume(struct drm_de
65 DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page);
66
67 if (dev_priv->status_gfx_addr != 0)
68- I915_WRITE(0x02080, dev_priv->status_gfx_addr);
69+ I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr);
70 else
71- I915_WRITE(0x02080, dev_priv->dma_status_page);
72+ I915_WRITE(HWS_PGA, dev_priv->dma_status_page);
73 DRM_DEBUG("Enabled hardware status page\n");
74
75 return 0;
76@@ -402,8 +402,8 @@ static void i915_emit_breadcrumb(struct
77 dev_priv->sarea_priv->last_enqueue = dev_priv->counter = 1;
78
79 BEGIN_LP_RING(4);
80- OUT_RING(CMD_STORE_DWORD_IDX);
81- OUT_RING(20);
82+ OUT_RING(MI_STORE_DWORD_INDEX);
83+ OUT_RING(5 << MI_STORE_DWORD_INDEX_SHIFT);
84 OUT_RING(dev_priv->counter);
85 OUT_RING(0);
86 ADVANCE_LP_RING();
87@@ -505,7 +505,7 @@ static int i915_dispatch_flip(struct drm
88 i915_kernel_lost_context(dev);
89
90 BEGIN_LP_RING(2);
91- OUT_RING(INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE);
92+ OUT_RING(MI_FLUSH | MI_READ_FLUSH);
93 OUT_RING(0);
94 ADVANCE_LP_RING();
95
96@@ -530,8 +530,8 @@ static int i915_dispatch_flip(struct drm
97 dev_priv->sarea_priv->last_enqueue = dev_priv->counter++;
98
99 BEGIN_LP_RING(4);
100- OUT_RING(CMD_STORE_DWORD_IDX);
101- OUT_RING(20);
102+ OUT_RING(MI_STORE_DWORD_INDEX);
103+ OUT_RING(5 << MI_STORE_DWORD_INDEX_SHIFT);
104 OUT_RING(dev_priv->counter);
105 OUT_RING(0);
106 ADVANCE_LP_RING();
107@@ -728,8 +728,8 @@ static int i915_set_status_page(struct d
108 dev_priv->hw_status_page = dev_priv->hws_map.handle;
109
110 memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
111- I915_WRITE(0x02080, dev_priv->status_gfx_addr);
112- DRM_DEBUG("load hws 0x2080 with gfx mem 0x%x\n",
113+ I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr);
114+ DRM_DEBUG("load hws HWS_PGA with gfx mem 0x%x\n",
115 dev_priv->status_gfx_addr);
116 DRM_DEBUG("load hws at %p\n", dev_priv->hw_status_page);
117 return 0;
118--- a/drivers/gpu/drm/i915/i915_drv.c
119+++ b/drivers/gpu/drm/i915/i915_drv.c
120@@ -279,13 +279,13 @@ static int i915_suspend(struct drm_devic
121 dev_priv->saveDSPASTRIDE = I915_READ(DSPASTRIDE);
122 dev_priv->saveDSPASIZE = I915_READ(DSPASIZE);
123 dev_priv->saveDSPAPOS = I915_READ(DSPAPOS);
124- dev_priv->saveDSPABASE = I915_READ(DSPABASE);
125+ dev_priv->saveDSPAADDR = I915_READ(DSPAADDR);
126 if (IS_I965G(dev)) {
127 dev_priv->saveDSPASURF = I915_READ(DSPASURF);
128 dev_priv->saveDSPATILEOFF = I915_READ(DSPATILEOFF);
129 }
130 i915_save_palette(dev, PIPE_A);
131- dev_priv->savePIPEASTAT = I915_READ(I915REG_PIPEASTAT);
132+ dev_priv->savePIPEASTAT = I915_READ(PIPEASTAT);
133
134 /* Pipe & plane B info */
135 dev_priv->savePIPEBCONF = I915_READ(PIPEBCONF);
136@@ -307,13 +307,13 @@ static int i915_suspend(struct drm_devic
137 dev_priv->saveDSPBSTRIDE = I915_READ(DSPBSTRIDE);
138 dev_priv->saveDSPBSIZE = I915_READ(DSPBSIZE);
139 dev_priv->saveDSPBPOS = I915_READ(DSPBPOS);
140- dev_priv->saveDSPBBASE = I915_READ(DSPBBASE);
141+ dev_priv->saveDSPBADDR = I915_READ(DSPBADDR);
142 if (IS_I965GM(dev) || IS_IGD_GM(dev)) {
143 dev_priv->saveDSPBSURF = I915_READ(DSPBSURF);
144 dev_priv->saveDSPBTILEOFF = I915_READ(DSPBTILEOFF);
145 }
146 i915_save_palette(dev, PIPE_B);
147- dev_priv->savePIPEBSTAT = I915_READ(I915REG_PIPEBSTAT);
148+ dev_priv->savePIPEBSTAT = I915_READ(PIPEBSTAT);
149
150 /* CRT state */
151 dev_priv->saveADPA = I915_READ(ADPA);
152@@ -328,9 +328,9 @@ static int i915_suspend(struct drm_devic
153 dev_priv->saveLVDS = I915_READ(LVDS);
154 if (!IS_I830(dev) && !IS_845G(dev))
155 dev_priv->savePFIT_CONTROL = I915_READ(PFIT_CONTROL);
156- dev_priv->saveLVDSPP_ON = I915_READ(LVDSPP_ON);
157- dev_priv->saveLVDSPP_OFF = I915_READ(LVDSPP_OFF);
158- dev_priv->savePP_CYCLE = I915_READ(PP_CYCLE);
159+ dev_priv->savePP_ON_DELAYS = I915_READ(PP_ON_DELAYS);
160+ dev_priv->savePP_OFF_DELAYS = I915_READ(PP_OFF_DELAYS);
161+ dev_priv->savePP_DIVISOR = I915_READ(PP_DIVISOR);
162
163 /* FIXME: save TV & SDVO state */
164
165@@ -341,19 +341,19 @@ static int i915_suspend(struct drm_devic
166 dev_priv->saveFBC_CONTROL = I915_READ(FBC_CONTROL);
167
168 /* Interrupt state */
169- dev_priv->saveIIR = I915_READ(I915REG_INT_IDENTITY_R);
170- dev_priv->saveIER = I915_READ(I915REG_INT_ENABLE_R);
171- dev_priv->saveIMR = I915_READ(I915REG_INT_MASK_R);
172+ dev_priv->saveIIR = I915_READ(IIR);
173+ dev_priv->saveIER = I915_READ(IER);
174+ dev_priv->saveIMR = I915_READ(IMR);
175
176 /* VGA state */
177- dev_priv->saveVCLK_DIVISOR_VGA0 = I915_READ(VCLK_DIVISOR_VGA0);
178- dev_priv->saveVCLK_DIVISOR_VGA1 = I915_READ(VCLK_DIVISOR_VGA1);
179- dev_priv->saveVCLK_POST_DIV = I915_READ(VCLK_POST_DIV);
180+ dev_priv->saveVGA0 = I915_READ(VGA0);
181+ dev_priv->saveVGA1 = I915_READ(VGA1);
182+ dev_priv->saveVGA_PD = I915_READ(VGA_PD);
183 dev_priv->saveVGACNTRL = I915_READ(VGACNTRL);
184
185 /* Clock gating state */
186 dev_priv->saveD_STATE = I915_READ(D_STATE);
187- dev_priv->saveDSPCLK_GATE_D = I915_READ(DSPCLK_GATE_D);
188+ dev_priv->saveCG_2D_DIS = I915_READ(CG_2D_DIS);
189
190 /* Cache mode state */
191 dev_priv->saveCACHE_MODE_0 = I915_READ(CACHE_MODE_0);
192@@ -363,7 +363,7 @@ static int i915_suspend(struct drm_devic
193
194 /* Scratch space */
195 for (i = 0; i < 16; i++) {
196- dev_priv->saveSWF0[i] = I915_READ(SWF0 + (i << 2));
197+ dev_priv->saveSWF0[i] = I915_READ(SWF00 + (i << 2));
198 dev_priv->saveSWF1[i] = I915_READ(SWF10 + (i << 2));
199 }
200 for (i = 0; i < 3; i++)
201@@ -424,7 +424,7 @@ static int i915_resume(struct drm_device
202 I915_WRITE(DSPASIZE, dev_priv->saveDSPASIZE);
203 I915_WRITE(DSPAPOS, dev_priv->saveDSPAPOS);
204 I915_WRITE(PIPEASRC, dev_priv->savePIPEASRC);
205- I915_WRITE(DSPABASE, dev_priv->saveDSPABASE);
206+ I915_WRITE(DSPAADDR, dev_priv->saveDSPAADDR);
207 I915_WRITE(DSPASTRIDE, dev_priv->saveDSPASTRIDE);
208 if (IS_I965G(dev)) {
209 I915_WRITE(DSPASURF, dev_priv->saveDSPASURF);
210@@ -436,7 +436,7 @@ static int i915_resume(struct drm_device
211 i915_restore_palette(dev, PIPE_A);
212 /* Enable the plane */
213 I915_WRITE(DSPACNTR, dev_priv->saveDSPACNTR);
214- I915_WRITE(DSPABASE, I915_READ(DSPABASE));
215+ I915_WRITE(DSPAADDR, I915_READ(DSPAADDR));
216
217 /* Pipe & plane B info */
218 if (dev_priv->saveDPLL_B & DPLL_VCO_ENABLE) {
219@@ -466,7 +466,7 @@ static int i915_resume(struct drm_device
220 I915_WRITE(DSPBSIZE, dev_priv->saveDSPBSIZE);
221 I915_WRITE(DSPBPOS, dev_priv->saveDSPBPOS);
222 I915_WRITE(PIPEBSRC, dev_priv->savePIPEBSRC);
223- I915_WRITE(DSPBBASE, dev_priv->saveDSPBBASE);
224+ I915_WRITE(DSPBADDR, dev_priv->saveDSPBADDR);
225 I915_WRITE(DSPBSTRIDE, dev_priv->saveDSPBSTRIDE);
226 if (IS_I965G(dev)) {
227 I915_WRITE(DSPBSURF, dev_priv->saveDSPBSURF);
228@@ -478,7 +478,7 @@ static int i915_resume(struct drm_device
229 i915_restore_palette(dev, PIPE_B);
230 /* Enable the plane */
231 I915_WRITE(DSPBCNTR, dev_priv->saveDSPBCNTR);
232- I915_WRITE(DSPBBASE, I915_READ(DSPBBASE));
233+ I915_WRITE(DSPBADDR, I915_READ(DSPBADDR));
234
235 /* CRT state */
236 I915_WRITE(ADPA, dev_priv->saveADPA);
237@@ -493,9 +493,9 @@ static int i915_resume(struct drm_device
238
239 I915_WRITE(PFIT_PGM_RATIOS, dev_priv->savePFIT_PGM_RATIOS);
240 I915_WRITE(BLC_PWM_CTL, dev_priv->saveBLC_PWM_CTL);
241- I915_WRITE(LVDSPP_ON, dev_priv->saveLVDSPP_ON);
242- I915_WRITE(LVDSPP_OFF, dev_priv->saveLVDSPP_OFF);
243- I915_WRITE(PP_CYCLE, dev_priv->savePP_CYCLE);
244+ I915_WRITE(PP_ON_DELAYS, dev_priv->savePP_ON_DELAYS);
245+ I915_WRITE(PP_OFF_DELAYS, dev_priv->savePP_OFF_DELAYS);
246+ I915_WRITE(PP_DIVISOR, dev_priv->savePP_DIVISOR);
247 I915_WRITE(PP_CONTROL, dev_priv->savePP_CONTROL);
248
249 /* FIXME: restore TV & SDVO state */
250@@ -508,14 +508,14 @@ static int i915_resume(struct drm_device
251
252 /* VGA state */
253 I915_WRITE(VGACNTRL, dev_priv->saveVGACNTRL);
254- I915_WRITE(VCLK_DIVISOR_VGA0, dev_priv->saveVCLK_DIVISOR_VGA0);
255- I915_WRITE(VCLK_DIVISOR_VGA1, dev_priv->saveVCLK_DIVISOR_VGA1);
256- I915_WRITE(VCLK_POST_DIV, dev_priv->saveVCLK_POST_DIV);
257+ I915_WRITE(VGA0, dev_priv->saveVGA0);
258+ I915_WRITE(VGA1, dev_priv->saveVGA1);
259+ I915_WRITE(VGA_PD, dev_priv->saveVGA_PD);
260 udelay(150);
261
262 /* Clock gating state */
263 I915_WRITE (D_STATE, dev_priv->saveD_STATE);
264- I915_WRITE (DSPCLK_GATE_D, dev_priv->saveDSPCLK_GATE_D);
265+ I915_WRITE(CG_2D_DIS, dev_priv->saveCG_2D_DIS);
266
267 /* Cache mode state */
268 I915_WRITE (CACHE_MODE_0, dev_priv->saveCACHE_MODE_0 | 0xffff0000);
269@@ -524,7 +524,7 @@ static int i915_resume(struct drm_device
270 I915_WRITE (MI_ARB_STATE, dev_priv->saveMI_ARB_STATE | 0xffff0000);
271
272 for (i = 0; i < 16; i++) {
273- I915_WRITE(SWF0 + (i << 2), dev_priv->saveSWF0[i]);
274+ I915_WRITE(SWF00 + (i << 2), dev_priv->saveSWF0[i]);
275 I915_WRITE(SWF10 + (i << 2), dev_priv->saveSWF1[i+7]);
276 }
277 for (i = 0; i < 3; i++)
278--- a/drivers/gpu/drm/i915/i915_drv.h
279+++ b/drivers/gpu/drm/i915/i915_drv.h
280@@ -30,6 +30,8 @@
281 #ifndef _I915_DRV_H_
282 #define _I915_DRV_H_
283
284+#include "i915_reg.h"
285+
286 /* General customization:
287 */
288
289@@ -138,7 +140,7 @@ typedef struct drm_i915_private {
290 u32 saveDSPASTRIDE;
291 u32 saveDSPASIZE;
292 u32 saveDSPAPOS;
293- u32 saveDSPABASE;
294+ u32 saveDSPAADDR;
295 u32 saveDSPASURF;
296 u32 saveDSPATILEOFF;
297 u32 savePFIT_PGM_RATIOS;
298@@ -159,24 +161,24 @@ typedef struct drm_i915_private {
299 u32 saveDSPBSTRIDE;
300 u32 saveDSPBSIZE;
301 u32 saveDSPBPOS;
302- u32 saveDSPBBASE;
303+ u32 saveDSPBADDR;
304 u32 saveDSPBSURF;
305 u32 saveDSPBTILEOFF;
306- u32 saveVCLK_DIVISOR_VGA0;
307- u32 saveVCLK_DIVISOR_VGA1;
308- u32 saveVCLK_POST_DIV;
309+ u32 saveVGA0;
310+ u32 saveVGA1;
311+ u32 saveVGA_PD;
312 u32 saveVGACNTRL;
313 u32 saveADPA;
314 u32 saveLVDS;
315- u32 saveLVDSPP_ON;
316- u32 saveLVDSPP_OFF;
317+ u32 savePP_ON_DELAYS;
318+ u32 savePP_OFF_DELAYS;
319 u32 saveDVOA;
320 u32 saveDVOB;
321 u32 saveDVOC;
322 u32 savePP_ON;
323 u32 savePP_OFF;
324 u32 savePP_CONTROL;
325- u32 savePP_CYCLE;
326+ u32 savePP_DIVISOR;
327 u32 savePFIT_CONTROL;
328 u32 save_palette_a[256];
329 u32 save_palette_b[256];
330@@ -189,7 +191,7 @@ typedef struct drm_i915_private {
331 u32 saveIMR;
332 u32 saveCACHE_MODE_0;
333 u32 saveD_STATE;
334- u32 saveDSPCLK_GATE_D;
335+ u32 saveCG_2D_DIS;
336 u32 saveMI_ARB_STATE;
337 u32 saveSWF0[16];
338 u32 saveSWF1[16];
339@@ -283,816 +285,26 @@ extern void i915_mem_release(struct drm_
340 if (I915_VERBOSE) DRM_DEBUG("ADVANCE_LP_RING %x\n", outring); \
341 dev_priv->ring.tail = outring; \
342 dev_priv->ring.space -= outcount * 4; \
343- I915_WRITE(LP_RING + RING_TAIL, outring); \
344+ I915_WRITE(PRB0_TAIL, outring); \
345 } while(0)
346
347-extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
348-
349-/* Extended config space */
350-#define LBB 0xf4
351-
352-/* VGA stuff */
353-
354-#define VGA_ST01_MDA 0x3ba
355-#define VGA_ST01_CGA 0x3da
356-
357-#define VGA_MSR_WRITE 0x3c2
358-#define VGA_MSR_READ 0x3cc
359-#define VGA_MSR_MEM_EN (1<<1)
360-#define VGA_MSR_CGA_MODE (1<<0)
361-
362-#define VGA_SR_INDEX 0x3c4
363-#define VGA_SR_DATA 0x3c5
364-
365-#define VGA_AR_INDEX 0x3c0
366-#define VGA_AR_VID_EN (1<<5)
367-#define VGA_AR_DATA_WRITE 0x3c0
368-#define VGA_AR_DATA_READ 0x3c1
369-
370-#define VGA_GR_INDEX 0x3ce
371-#define VGA_GR_DATA 0x3cf
372-/* GR05 */
373-#define VGA_GR_MEM_READ_MODE_SHIFT 3
374-#define VGA_GR_MEM_READ_MODE_PLANE 1
375-/* GR06 */
376-#define VGA_GR_MEM_MODE_MASK 0xc
377-#define VGA_GR_MEM_MODE_SHIFT 2
378-#define VGA_GR_MEM_A0000_AFFFF 0
379-#define VGA_GR_MEM_A0000_BFFFF 1
380-#define VGA_GR_MEM_B0000_B7FFF 2
381-#define VGA_GR_MEM_B0000_BFFFF 3
382-
383-#define VGA_DACMASK 0x3c6
384-#define VGA_DACRX 0x3c7
385-#define VGA_DACWX 0x3c8
386-#define VGA_DACDATA 0x3c9
387-
388-#define VGA_CR_INDEX_MDA 0x3b4
389-#define VGA_CR_DATA_MDA 0x3b5
390-#define VGA_CR_INDEX_CGA 0x3d4
391-#define VGA_CR_DATA_CGA 0x3d5
392-
393-#define GFX_OP_USER_INTERRUPT ((0<<29)|(2<<23))
394-#define GFX_OP_BREAKPOINT_INTERRUPT ((0<<29)|(1<<23))
395-#define CMD_REPORT_HEAD (7<<23)
396-#define CMD_STORE_DWORD_IDX ((0x21<<23) | 0x1)
397-#define CMD_OP_BATCH_BUFFER ((0x0<<29)|(0x30<<23)|0x1)
398-
399-#define INST_PARSER_CLIENT 0x00000000
400-#define INST_OP_FLUSH 0x02000000
401-#define INST_FLUSH_MAP_CACHE 0x00000001
402-
403-#define BB1_START_ADDR_MASK (~0x7)
404-#define BB1_PROTECTED (1<<0)
405-#define BB1_UNPROTECTED (0<<0)
406-#define BB2_END_ADDR_MASK (~0x7)
407-
408-/* Framebuffer compression */
409-#define FBC_CFB_BASE 0x03200 /* 4k page aligned */
410-#define FBC_LL_BASE 0x03204 /* 4k page aligned */
411-#define FBC_CONTROL 0x03208
412-#define FBC_CTL_EN (1<<31)
413-#define FBC_CTL_PERIODIC (1<<30)
414-#define FBC_CTL_INTERVAL_SHIFT (16)
415-#define FBC_CTL_UNCOMPRESSIBLE (1<<14)
416-#define FBC_CTL_STRIDE_SHIFT (5)
417-#define FBC_CTL_FENCENO (1<<0)
418-#define FBC_COMMAND 0x0320c
419-#define FBC_CMD_COMPRESS (1<<0)
420-#define FBC_STATUS 0x03210
421-#define FBC_STAT_COMPRESSING (1<<31)
422-#define FBC_STAT_COMPRESSED (1<<30)
423-#define FBC_STAT_MODIFIED (1<<29)
424-#define FBC_STAT_CURRENT_LINE (1<<0)
425-#define FBC_CONTROL2 0x03214
426-#define FBC_CTL_FENCE_DBL (0<<4)
427-#define FBC_CTL_IDLE_IMM (0<<2)
428-#define FBC_CTL_IDLE_FULL (1<<2)
429-#define FBC_CTL_IDLE_LINE (2<<2)
430-#define FBC_CTL_IDLE_DEBUG (3<<2)
431-#define FBC_CTL_CPU_FENCE (1<<1)
432-#define FBC_CTL_PLANEA (0<<0)
433-#define FBC_CTL_PLANEB (1<<0)
434-#define FBC_FENCE_OFF 0x0321b
435-
436-#define FBC_LL_SIZE (1536)
437-#define FBC_LL_PAD (32)
438-
439-/* Interrupt bits:
440- */
441-#define USER_INT_FLAG (1<<1)
442-#define VSYNC_PIPEB_FLAG (1<<5)
443-#define VSYNC_PIPEA_FLAG (1<<7)
444-#define HWB_OOM_FLAG (1<<13) /* binner out of memory */
445-
446-#define I915REG_HWSTAM 0x02098
447-#define I915REG_INT_IDENTITY_R 0x020a4
448-#define I915REG_INT_MASK_R 0x020a8
449-#define I915REG_INT_ENABLE_R 0x020a0
450-
451-#define I915REG_PIPEASTAT 0x70024
452-#define I915REG_PIPEBSTAT 0x71024
453-
454-#define I915_VBLANK_INTERRUPT_ENABLE (1UL<<17)
455-#define I915_VBLANK_CLEAR (1UL<<1)
456-
457-#define SRX_INDEX 0x3c4
458-#define SRX_DATA 0x3c5
459-#define SR01 1
460-#define SR01_SCREEN_OFF (1<<5)
461-
462-#define PPCR 0x61204
463-#define PPCR_ON (1<<0)
464-
465-#define DVOB 0x61140
466-#define DVOB_ON (1<<31)
467-#define DVOC 0x61160
468-#define DVOC_ON (1<<31)
469-#define LVDS 0x61180
470-#define LVDS_ON (1<<31)
471-
472-#define ADPA 0x61100
473-#define ADPA_DPMS_MASK (~(3<<10))
474-#define ADPA_DPMS_ON (0<<10)
475-#define ADPA_DPMS_SUSPEND (1<<10)
476-#define ADPA_DPMS_STANDBY (2<<10)
477-#define ADPA_DPMS_OFF (3<<10)
478-
479-#define NOPID 0x2094
480-#define LP_RING 0x2030
481-#define HP_RING 0x2040
482-/* The binner has its own ring buffer:
483- */
484-#define HWB_RING 0x2400
485-
486-#define RING_TAIL 0x00
487-#define TAIL_ADDR 0x001FFFF8
488-#define RING_HEAD 0x04
489-#define HEAD_WRAP_COUNT 0xFFE00000
490-#define HEAD_WRAP_ONE 0x00200000
491-#define HEAD_ADDR 0x001FFFFC
492-#define RING_START 0x08
493-#define START_ADDR 0x0xFFFFF000
494-#define RING_LEN 0x0C
495-#define RING_NR_PAGES 0x001FF000
496-#define RING_REPORT_MASK 0x00000006
497-#define RING_REPORT_64K 0x00000002
498-#define RING_REPORT_128K 0x00000004
499-#define RING_NO_REPORT 0x00000000
500-#define RING_VALID_MASK 0x00000001
501-#define RING_VALID 0x00000001
502-#define RING_INVALID 0x00000000
503-
504-/* Instruction parser error reg:
505- */
506-#define IPEIR 0x2088
507-
508-/* Scratch pad debug 0 reg:
509- */
510-#define SCPD0 0x209c
511-
512-/* Error status reg:
513- */
514-#define ESR 0x20b8
515-
516-/* Secondary DMA fetch address debug reg:
517- */
518-#define DMA_FADD_S 0x20d4
519-
520-/* Memory Interface Arbitration State
521- */
522-#define MI_ARB_STATE 0x20e4
523-
524-/* Cache mode 0 reg.
525- * - Manipulating render cache behaviour is central
526- * to the concept of zone rendering, tuning this reg can help avoid
527- * unnecessary render cache reads and even writes (for z/stencil)
528- * at beginning and end of scene.
529- *
530- * - To change a bit, write to this reg with a mask bit set and the
531- * bit of interest either set or cleared. EG: (BIT<<16) | BIT to set.
532- */
533-#define Cache_Mode_0 0x2120
534-#define CACHE_MODE_0 0x2120
535-#define CM0_MASK_SHIFT 16
536-#define CM0_IZ_OPT_DISABLE (1<<6)
537-#define CM0_ZR_OPT_DISABLE (1<<5)
538-#define CM0_DEPTH_EVICT_DISABLE (1<<4)
539-#define CM0_COLOR_EVICT_DISABLE (1<<3)
540-#define CM0_DEPTH_WRITE_DISABLE (1<<1)
541-#define CM0_RC_OP_FLUSH_DISABLE (1<<0)
542-
543-
544-/* Graphics flush control. A CPU write flushes the GWB of all writes.
545- * The data is discarded.
546- */
547-#define GFX_FLSH_CNTL 0x2170
548-
549-/* Binner control. Defines the location of the bin pointer list:
550- */
551-#define BINCTL 0x2420
552-#define BC_MASK (1 << 9)
553-
554-/* Binned scene info.
555- */
556-#define BINSCENE 0x2428
557-#define BS_OP_LOAD (1 << 8)
558-#define BS_MASK (1 << 22)
559-
560-/* Bin command parser debug reg:
561- */
562-#define BCPD 0x2480
563-
564-/* Bin memory control debug reg:
565- */
566-#define BMCD 0x2484
567-
568-/* Bin data cache debug reg:
569- */
570-#define BDCD 0x2488
571-
572-/* Binner pointer cache debug reg:
573- */
574-#define BPCD 0x248c
575-
576-/* Binner scratch pad debug reg:
577- */
578-#define BINSKPD 0x24f0
579-
580-/* HWB scratch pad debug reg:
581- */
582-#define HWBSKPD 0x24f4
583-
584-/* Binner memory pool reg:
585- */
586-#define BMP_BUFFER 0x2430
587-#define BMP_PAGE_SIZE_4K (0 << 10)
588-#define BMP_BUFFER_SIZE_SHIFT 1
589-#define BMP_ENABLE (1 << 0)
590-
591-/* Get/put memory from the binner memory pool:
592- */
593-#define BMP_GET 0x2438
594-#define BMP_PUT 0x2440
595-#define BMP_OFFSET_SHIFT 5
596-
597-/* 3D state packets:
598- */
599-#define GFX_OP_RASTER_RULES ((0x3<<29)|(0x7<<24))
600-
601-#define GFX_OP_SCISSOR ((0x3<<29)|(0x1c<<24)|(0x10<<19))
602-#define SC_UPDATE_SCISSOR (0x1<<1)
603-#define SC_ENABLE_MASK (0x1<<0)
604-#define SC_ENABLE (0x1<<0)
605-
606-#define GFX_OP_LOAD_INDIRECT ((0x3<<29)|(0x1d<<24)|(0x7<<16))
607-
608-#define GFX_OP_SCISSOR_INFO ((0x3<<29)|(0x1d<<24)|(0x81<<16)|(0x1))
609-#define SCI_YMIN_MASK (0xffff<<16)
610-#define SCI_XMIN_MASK (0xffff<<0)
611-#define SCI_YMAX_MASK (0xffff<<16)
612-#define SCI_XMAX_MASK (0xffff<<0)
613-
614-#define GFX_OP_SCISSOR_ENABLE ((0x3<<29)|(0x1c<<24)|(0x10<<19))
615-#define GFX_OP_SCISSOR_RECT ((0x3<<29)|(0x1d<<24)|(0x81<<16)|1)
616-#define GFX_OP_COLOR_FACTOR ((0x3<<29)|(0x1d<<24)|(0x1<<16)|0x0)
617-#define GFX_OP_STIPPLE ((0x3<<29)|(0x1d<<24)|(0x83<<16))
618-#define GFX_OP_MAP_INFO ((0x3<<29)|(0x1d<<24)|0x4)
619-#define GFX_OP_DESTBUFFER_VARS ((0x3<<29)|(0x1d<<24)|(0x85<<16)|0x0)
620-#define GFX_OP_DRAWRECT_INFO ((0x3<<29)|(0x1d<<24)|(0x80<<16)|(0x3))
621-
622-#define GFX_OP_DRAWRECT_INFO_I965 ((0x7900<<16)|0x2)
623-
624-#define SRC_COPY_BLT_CMD ((2<<29)|(0x43<<22)|4)
625-#define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6)
626-#define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21)
627-#define XY_SRC_COPY_BLT_WRITE_RGB (1<<20)
628-#define XY_SRC_COPY_BLT_SRC_TILED (1<<15)
629-#define XY_SRC_COPY_BLT_DST_TILED (1<<11)
630-
631-#define MI_BATCH_BUFFER ((0x30<<23)|1)
632-#define MI_BATCH_BUFFER_START (0x31<<23)
633-#define MI_BATCH_BUFFER_END (0xA<<23)
634-#define MI_BATCH_NON_SECURE (1)
635-#define MI_BATCH_NON_SECURE_I965 (1<<8)
636-
637-#define MI_WAIT_FOR_EVENT ((0x3<<23))
638-#define MI_WAIT_FOR_PLANE_B_FLIP (1<<6)
639-#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2)
640-#define MI_WAIT_FOR_PLANE_A_SCANLINES (1<<1)
641-
642-#define MI_LOAD_SCAN_LINES_INCL ((0x12<<23))
643-
644-#define CMD_OP_DISPLAYBUFFER_INFO ((0x0<<29)|(0x14<<23)|2)
645-#define ASYNC_FLIP (1<<22)
646-#define DISPLAY_PLANE_A (0<<20)
647-#define DISPLAY_PLANE_B (1<<20)
648-
649-/* Display regs */
650-#define DSPACNTR 0x70180
651-#define DSPBCNTR 0x71180
652-#define DISPPLANE_SEL_PIPE_MASK (1<<24)
653-
654-/* Define the region of interest for the binner:
655- */
656-#define CMD_OP_BIN_CONTROL ((0x3<<29)|(0x1d<<24)|(0x84<<16)|4)
657-
658-#define CMD_OP_DESTBUFFER_INFO ((0x3<<29)|(0x1d<<24)|(0x8e<<16)|1)
659-
660-#define CMD_MI_FLUSH (0x04 << 23)
661-#define MI_NO_WRITE_FLUSH (1 << 2)
662-#define MI_READ_FLUSH (1 << 0)
663-#define MI_EXE_FLUSH (1 << 1)
664-#define MI_END_SCENE (1 << 4) /* flush binner and incr scene count */
665-#define MI_SCENE_COUNT (1 << 3) /* just increment scene count */
666-
667-#define BREADCRUMB_BITS 31
668-#define BREADCRUMB_MASK ((1U << BREADCRUMB_BITS) - 1)
669-
670-#define READ_BREADCRUMB(dev_priv) (((volatile u32*)(dev_priv->hw_status_page))[5])
671-#define READ_HWSP(dev_priv, reg) (((volatile u32*)(dev_priv->hw_status_page))[reg])
672-
673-#define BLC_PWM_CTL 0x61254
674-#define BACKLIGHT_MODULATION_FREQ_SHIFT (17)
675-
676-#define BLC_PWM_CTL2 0x61250
677 /**
678- * This is the most significant 15 bits of the number of backlight cycles in a
679- * complete cycle of the modulated backlight control.
680+ * Reads a dword out of the status page, which is written to from the command
681+ * queue by automatic updates, MI_REPORT_HEAD, MI_STORE_DATA_INDEX, or
682+ * MI_STORE_DATA_IMM.
683+ *
684+ * The following dwords have a reserved meaning:
685+ * 0: ISR copy, updated when an ISR bit not set in the HWSTAM changes.
686+ * 4: ring 0 head pointer
687+ * 5: ring 1 head pointer (915-class)
688+ * 6: ring 2 head pointer (915-class)
689 *
690- * The actual value is this field multiplied by two.
691+ * The area from dword 0x10 to 0x3ff is available for driver usage.
692 */
693-#define BACKLIGHT_MODULATION_FREQ_MASK (0x7fff << 17)
694-#define BLM_LEGACY_MODE (1 << 16)
695-/**
696- * This is the number of cycles out of the backlight modulation cycle for which
697- * the backlight is on.
698- *
699- * This field must be no greater than the number of cycles in the complete
700- * backlight modulation cycle.
701- */
702-#define BACKLIGHT_DUTY_CYCLE_SHIFT (0)
703-#define BACKLIGHT_DUTY_CYCLE_MASK (0xffff)
704-
705-#define I915_GCFGC 0xf0
706-#define I915_LOW_FREQUENCY_ENABLE (1 << 7)
707-#define I915_DISPLAY_CLOCK_190_200_MHZ (0 << 4)
708-#define I915_DISPLAY_CLOCK_333_MHZ (4 << 4)
709-#define I915_DISPLAY_CLOCK_MASK (7 << 4)
710-
711-#define I855_HPLLCC 0xc0
712-#define I855_CLOCK_CONTROL_MASK (3 << 0)
713-#define I855_CLOCK_133_200 (0 << 0)
714-#define I855_CLOCK_100_200 (1 << 0)
715-#define I855_CLOCK_100_133 (2 << 0)
716-#define I855_CLOCK_166_250 (3 << 0)
717-
718-/* p317, 319
719- */
720-#define VCLK2_VCO_M 0x6008 /* treat as 16 bit? (includes msbs) */
721-#define VCLK2_VCO_N 0x600a
722-#define VCLK2_VCO_DIV_SEL 0x6012
723-
724-#define VCLK_DIVISOR_VGA0 0x6000
725-#define VCLK_DIVISOR_VGA1 0x6004
726-#define VCLK_POST_DIV 0x6010
727-/** Selects a post divisor of 4 instead of 2. */
728-# define VGA1_PD_P2_DIV_4 (1 << 15)
729-/** Overrides the p2 post divisor field */
730-# define VGA1_PD_P1_DIV_2 (1 << 13)
731-# define VGA1_PD_P1_SHIFT 8
732-/** P1 value is 2 greater than this field */
733-# define VGA1_PD_P1_MASK (0x1f << 8)
734-/** Selects a post divisor of 4 instead of 2. */
735-# define VGA0_PD_P2_DIV_4 (1 << 7)
736-/** Overrides the p2 post divisor field */
737-# define VGA0_PD_P1_DIV_2 (1 << 5)
738-# define VGA0_PD_P1_SHIFT 0
739-/** P1 value is 2 greater than this field */
740-# define VGA0_PD_P1_MASK (0x1f << 0)
741-
742-/* PCI D state control register */
743-#define D_STATE 0x6104
744-#define DSPCLK_GATE_D 0x6200
745-
746-/* I830 CRTC registers */
747-#define HTOTAL_A 0x60000
748-#define HBLANK_A 0x60004
749-#define HSYNC_A 0x60008
750-#define VTOTAL_A 0x6000c
751-#define VBLANK_A 0x60010
752-#define VSYNC_A 0x60014
753-#define PIPEASRC 0x6001c
754-#define BCLRPAT_A 0x60020
755-#define VSYNCSHIFT_A 0x60028
756-
757-#define HTOTAL_B 0x61000
758-#define HBLANK_B 0x61004
759-#define HSYNC_B 0x61008
760-#define VTOTAL_B 0x6100c
761-#define VBLANK_B 0x61010
762-#define VSYNC_B 0x61014
763-#define PIPEBSRC 0x6101c
764-#define BCLRPAT_B 0x61020
765-#define VSYNCSHIFT_B 0x61028
766-
767-#define PP_STATUS 0x61200
768-# define PP_ON (1 << 31)
769-/**
770- * Indicates that all dependencies of the panel are on:
771- *
772- * - PLL enabled
773- * - pipe enabled
774- * - LVDS/DVOB/DVOC on
775- */
776-# define PP_READY (1 << 30)
777-# define PP_SEQUENCE_NONE (0 << 28)
778-# define PP_SEQUENCE_ON (1 << 28)
779-# define PP_SEQUENCE_OFF (2 << 28)
780-# define PP_SEQUENCE_MASK 0x30000000
781-#define PP_CONTROL 0x61204
782-# define POWER_TARGET_ON (1 << 0)
783-
784-#define LVDSPP_ON 0x61208
785-#define LVDSPP_OFF 0x6120c
786-#define PP_CYCLE 0x61210
787-
788-#define PFIT_CONTROL 0x61230
789-# define PFIT_ENABLE (1 << 31)
790-# define PFIT_PIPE_MASK (3 << 29)
791-# define PFIT_PIPE_SHIFT 29
792-# define VERT_INTERP_DISABLE (0 << 10)
793-# define VERT_INTERP_BILINEAR (1 << 10)
794-# define VERT_INTERP_MASK (3 << 10)
795-# define VERT_AUTO_SCALE (1 << 9)
796-# define HORIZ_INTERP_DISABLE (0 << 6)
797-# define HORIZ_INTERP_BILINEAR (1 << 6)
798-# define HORIZ_INTERP_MASK (3 << 6)
799-# define HORIZ_AUTO_SCALE (1 << 5)
800-# define PANEL_8TO6_DITHER_ENABLE (1 << 3)
801-
802-#define PFIT_PGM_RATIOS 0x61234
803-# define PFIT_VERT_SCALE_MASK 0xfff00000
804-# define PFIT_HORIZ_SCALE_MASK 0x0000fff0
805-
806-#define PFIT_AUTO_RATIOS 0x61238
807-
808-
809-#define DPLL_A 0x06014
810-#define DPLL_B 0x06018
811-# define DPLL_VCO_ENABLE (1 << 31)
812-# define DPLL_DVO_HIGH_SPEED (1 << 30)
813-# define DPLL_SYNCLOCK_ENABLE (1 << 29)
814-# define DPLL_VGA_MODE_DIS (1 << 28)
815-# define DPLLB_MODE_DAC_SERIAL (1 << 26) /* i915 */
816-# define DPLLB_MODE_LVDS (2 << 26) /* i915 */
817-# define DPLL_MODE_MASK (3 << 26)
818-# define DPLL_DAC_SERIAL_P2_CLOCK_DIV_10 (0 << 24) /* i915 */
819-# define DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 (1 << 24) /* i915 */
820-# define DPLLB_LVDS_P2_CLOCK_DIV_14 (0 << 24) /* i915 */
821-# define DPLLB_LVDS_P2_CLOCK_DIV_7 (1 << 24) /* i915 */
822-# define DPLL_P2_CLOCK_DIV_MASK 0x03000000 /* i915 */
823-# define DPLL_FPA01_P1_POST_DIV_MASK 0x00ff0000 /* i915 */
824-/**
825- * The i830 generation, in DAC/serial mode, defines p1 as two plus this
826- * bitfield, or just 2 if PLL_P1_DIVIDE_BY_TWO is set.
827- */
828-# define DPLL_FPA01_P1_POST_DIV_MASK_I830 0x001f0000
829-/**
830- * The i830 generation, in LVDS mode, defines P1 as the bit number set within
831- * this field (only one bit may be set).
832- */
833-# define DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS 0x003f0000
834-# define DPLL_FPA01_P1_POST_DIV_SHIFT 16
835-# define PLL_P2_DIVIDE_BY_4 (1 << 23) /* i830, required in DVO non-gang */
836-# define PLL_P1_DIVIDE_BY_TWO (1 << 21) /* i830 */
837-# define PLL_REF_INPUT_DREFCLK (0 << 13)
838-# define PLL_REF_INPUT_TVCLKINA (1 << 13) /* i830 */
839-# define PLL_REF_INPUT_TVCLKINBC (2 << 13) /* SDVO TVCLKIN */
840-# define PLLB_REF_INPUT_SPREADSPECTRUMIN (3 << 13)
841-# define PLL_REF_INPUT_MASK (3 << 13)
842-# define PLL_LOAD_PULSE_PHASE_SHIFT 9
843-/*
844- * Parallel to Serial Load Pulse phase selection.
845- * Selects the phase for the 10X DPLL clock for the PCIe
846- * digital display port. The range is 4 to 13; 10 or more
847- * is just a flip delay. The default is 6
848- */
849-# define PLL_LOAD_PULSE_PHASE_MASK (0xf << PLL_LOAD_PULSE_PHASE_SHIFT)
850-# define DISPLAY_RATE_SELECT_FPA1 (1 << 8)
851-
852-/**
853- * SDVO multiplier for 945G/GM. Not used on 965.
854- *
855- * \sa DPLL_MD_UDI_MULTIPLIER_MASK
856- */
857-# define SDVO_MULTIPLIER_MASK 0x000000ff
858-# define SDVO_MULTIPLIER_SHIFT_HIRES 4
859-# define SDVO_MULTIPLIER_SHIFT_VGA 0
860-
861-/** @defgroup DPLL_MD
862- * @{
863- */
864-/** Pipe A SDVO/UDI clock multiplier/divider register for G965. */
865-#define DPLL_A_MD 0x0601c
866-/** Pipe B SDVO/UDI clock multiplier/divider register for G965. */
867-#define DPLL_B_MD 0x06020
868-/**
869- * UDI pixel divider, controlling how many pixels are stuffed into a packet.
870- *
871- * Value is pixels minus 1. Must be set to 1 pixel for SDVO.
872- */
873-# define DPLL_MD_UDI_DIVIDER_MASK 0x3f000000
874-# define DPLL_MD_UDI_DIVIDER_SHIFT 24
875-/** UDI pixel divider for VGA, same as DPLL_MD_UDI_DIVIDER_MASK. */
876-# define DPLL_MD_VGA_UDI_DIVIDER_MASK 0x003f0000
877-# define DPLL_MD_VGA_UDI_DIVIDER_SHIFT 16
878-/**
879- * SDVO/UDI pixel multiplier.
880- *
881- * SDVO requires that the bus clock rate be between 1 and 2 Ghz, and the bus
882- * clock rate is 10 times the DPLL clock. At low resolution/refresh rate
883- * modes, the bus rate would be below the limits, so SDVO allows for stuffing
884- * dummy bytes in the datastream at an increased clock rate, with both sides of
885- * the link knowing how many bytes are fill.
886- *
887- * So, for a mode with a dotclock of 65Mhz, we would want to double the clock
888- * rate to 130Mhz to get a bus rate of 1.30Ghz. The DPLL clock rate would be
889- * set to 130Mhz, and the SDVO multiplier set to 2x in this register and
890- * through an SDVO command.
891- *
892- * This register field has values of multiplication factor minus 1, with
893- * a maximum multiplier of 5 for SDVO.
894- */
895-# define DPLL_MD_UDI_MULTIPLIER_MASK 0x00003f00
896-# define DPLL_MD_UDI_MULTIPLIER_SHIFT 8
897-/** SDVO/UDI pixel multiplier for VGA, same as DPLL_MD_UDI_MULTIPLIER_MASK.
898- * This best be set to the default value (3) or the CRT won't work. No,
899- * I don't entirely understand what this does...
900- */
901-# define DPLL_MD_VGA_UDI_MULTIPLIER_MASK 0x0000003f
902-# define DPLL_MD_VGA_UDI_MULTIPLIER_SHIFT 0
903-/** @} */
904-
905-#define DPLL_TEST 0x606c
906-# define DPLLB_TEST_SDVO_DIV_1 (0 << 22)
907-# define DPLLB_TEST_SDVO_DIV_2 (1 << 22)
908-# define DPLLB_TEST_SDVO_DIV_4 (2 << 22)
909-# define DPLLB_TEST_SDVO_DIV_MASK (3 << 22)
910-# define DPLLB_TEST_N_BYPASS (1 << 19)
911-# define DPLLB_TEST_M_BYPASS (1 << 18)
912-# define DPLLB_INPUT_BUFFER_ENABLE (1 << 16)
913-# define DPLLA_TEST_N_BYPASS (1 << 3)
914-# define DPLLA_TEST_M_BYPASS (1 << 2)
915-# define DPLLA_INPUT_BUFFER_ENABLE (1 << 0)
916-
917-#define ADPA 0x61100
918-#define ADPA_DAC_ENABLE (1<<31)
919-#define ADPA_DAC_DISABLE 0
920-#define ADPA_PIPE_SELECT_MASK (1<<30)
921-#define ADPA_PIPE_A_SELECT 0
922-#define ADPA_PIPE_B_SELECT (1<<30)
923-#define ADPA_USE_VGA_HVPOLARITY (1<<15)
924-#define ADPA_SETS_HVPOLARITY 0
925-#define ADPA_VSYNC_CNTL_DISABLE (1<<11)
926-#define ADPA_VSYNC_CNTL_ENABLE 0
927-#define ADPA_HSYNC_CNTL_DISABLE (1<<10)
928-#define ADPA_HSYNC_CNTL_ENABLE 0
929-#define ADPA_VSYNC_ACTIVE_HIGH (1<<4)
930-#define ADPA_VSYNC_ACTIVE_LOW 0
931-#define ADPA_HSYNC_ACTIVE_HIGH (1<<3)
932-#define ADPA_HSYNC_ACTIVE_LOW 0
933-
934-#define FPA0 0x06040
935-#define FPA1 0x06044
936-#define FPB0 0x06048
937-#define FPB1 0x0604c
938-# define FP_N_DIV_MASK 0x003f0000
939-# define FP_N_DIV_SHIFT 16
940-# define FP_M1_DIV_MASK 0x00003f00
941-# define FP_M1_DIV_SHIFT 8
942-# define FP_M2_DIV_MASK 0x0000003f
943-# define FP_M2_DIV_SHIFT 0
944-
945-
946-#define PORT_HOTPLUG_EN 0x61110
947-# define SDVOB_HOTPLUG_INT_EN (1 << 26)
948-# define SDVOC_HOTPLUG_INT_EN (1 << 25)
949-# define TV_HOTPLUG_INT_EN (1 << 18)
950-# define CRT_HOTPLUG_INT_EN (1 << 9)
951-# define CRT_HOTPLUG_FORCE_DETECT (1 << 3)
952-
953-#define PORT_HOTPLUG_STAT 0x61114
954-# define CRT_HOTPLUG_INT_STATUS (1 << 11)
955-# define TV_HOTPLUG_INT_STATUS (1 << 10)
956-# define CRT_HOTPLUG_MONITOR_MASK (3 << 8)
957-# define CRT_HOTPLUG_MONITOR_COLOR (3 << 8)
958-# define CRT_HOTPLUG_MONITOR_MONO (2 << 8)
959-# define CRT_HOTPLUG_MONITOR_NONE (0 << 8)
960-# define SDVOC_HOTPLUG_INT_STATUS (1 << 7)
961-# define SDVOB_HOTPLUG_INT_STATUS (1 << 6)
962-
963-#define SDVOB 0x61140
964-#define SDVOC 0x61160
965-#define SDVO_ENABLE (1 << 31)
966-#define SDVO_PIPE_B_SELECT (1 << 30)
967-#define SDVO_STALL_SELECT (1 << 29)
968-#define SDVO_INTERRUPT_ENABLE (1 << 26)
969-/**
970- * 915G/GM SDVO pixel multiplier.
971- *
972- * Programmed value is multiplier - 1, up to 5x.
973- *
974- * \sa DPLL_MD_UDI_MULTIPLIER_MASK
975- */
976-#define SDVO_PORT_MULTIPLY_MASK (7 << 23)
977-#define SDVO_PORT_MULTIPLY_SHIFT 23
978-#define SDVO_PHASE_SELECT_MASK (15 << 19)
979-#define SDVO_PHASE_SELECT_DEFAULT (6 << 19)
980-#define SDVO_CLOCK_OUTPUT_INVERT (1 << 18)
981-#define SDVOC_GANG_MODE (1 << 16)
982-#define SDVO_BORDER_ENABLE (1 << 7)
983-#define SDVOB_PCIE_CONCURRENCY (1 << 3)
984-#define SDVO_DETECTED (1 << 2)
985-/* Bits to be preserved when writing */
986-#define SDVOB_PRESERVE_MASK ((1 << 17) | (1 << 16) | (1 << 14))
987-#define SDVOC_PRESERVE_MASK (1 << 17)
988-
989-/** @defgroup LVDS
990- * @{
991- */
992-/**
993- * This register controls the LVDS output enable, pipe selection, and data
994- * format selection.
995- *
996- * All of the clock/data pairs are force powered down by power sequencing.
997- */
998-#define LVDS 0x61180
999-/**
1000- * Enables the LVDS port. This bit must be set before DPLLs are enabled, as
1001- * the DPLL semantics change when the LVDS is assigned to that pipe.
1002- */
1003-# define LVDS_PORT_EN (1 << 31)
1004-/** Selects pipe B for LVDS data. Must be set on pre-965. */
1005-# define LVDS_PIPEB_SELECT (1 << 30)
1006-
1007-/**
1008- * Enables the A0-A2 data pairs and CLKA, containing 18 bits of color data per
1009- * pixel.
1010- */
1011-# define LVDS_A0A2_CLKA_POWER_MASK (3 << 8)
1012-# define LVDS_A0A2_CLKA_POWER_DOWN (0 << 8)
1013-# define LVDS_A0A2_CLKA_POWER_UP (3 << 8)
1014-/**
1015- * Controls the A3 data pair, which contains the additional LSBs for 24 bit
1016- * mode. Only enabled if LVDS_A0A2_CLKA_POWER_UP also indicates it should be
1017- * on.
1018- */
1019-# define LVDS_A3_POWER_MASK (3 << 6)
1020-# define LVDS_A3_POWER_DOWN (0 << 6)
1021-# define LVDS_A3_POWER_UP (3 << 6)
1022-/**
1023- * Controls the CLKB pair. This should only be set when LVDS_B0B3_POWER_UP
1024- * is set.
1025- */
1026-# define LVDS_CLKB_POWER_MASK (3 << 4)
1027-# define LVDS_CLKB_POWER_DOWN (0 << 4)
1028-# define LVDS_CLKB_POWER_UP (3 << 4)
1029-
1030-/**
1031- * Controls the B0-B3 data pairs. This must be set to match the DPLL p2
1032- * setting for whether we are in dual-channel mode. The B3 pair will
1033- * additionally only be powered up when LVDS_A3_POWER_UP is set.
1034- */
1035-# define LVDS_B0B3_POWER_MASK (3 << 2)
1036-# define LVDS_B0B3_POWER_DOWN (0 << 2)
1037-# define LVDS_B0B3_POWER_UP (3 << 2)
1038-
1039-#define PIPEACONF 0x70008
1040-#define PIPEACONF_ENABLE (1<<31)
1041-#define PIPEACONF_DISABLE 0
1042-#define PIPEACONF_DOUBLE_WIDE (1<<30)
1043-#define I965_PIPECONF_ACTIVE (1<<30)
1044-#define PIPEACONF_SINGLE_WIDE 0
1045-#define PIPEACONF_PIPE_UNLOCKED 0
1046-#define PIPEACONF_PIPE_LOCKED (1<<25)
1047-#define PIPEACONF_PALETTE 0
1048-#define PIPEACONF_GAMMA (1<<24)
1049-#define PIPECONF_FORCE_BORDER (1<<25)
1050-#define PIPECONF_PROGRESSIVE (0 << 21)
1051-#define PIPECONF_INTERLACE_W_FIELD_INDICATION (6 << 21)
1052-#define PIPECONF_INTERLACE_FIELD_0_ONLY (7 << 21)
1053-
1054-#define DSPARB 0x70030
1055-#define DSPARB_CSTART_MASK (0x7f << 7)
1056-#define DSPARB_CSTART_SHIFT 7
1057-#define DSPARB_BSTART_MASK (0x7f)
1058-#define DSPARB_BSTART_SHIFT 0
1059-
1060-#define PIPEBCONF 0x71008
1061-#define PIPEBCONF_ENABLE (1<<31)
1062-#define PIPEBCONF_DISABLE 0
1063-#define PIPEBCONF_DOUBLE_WIDE (1<<30)
1064-#define PIPEBCONF_DISABLE 0
1065-#define PIPEBCONF_GAMMA (1<<24)
1066-#define PIPEBCONF_PALETTE 0
1067-
1068-#define PIPEBGCMAXRED 0x71010
1069-#define PIPEBGCMAXGREEN 0x71014
1070-#define PIPEBGCMAXBLUE 0x71018
1071-#define PIPEBSTAT 0x71024
1072-#define PIPEBFRAMEHIGH 0x71040
1073-#define PIPEBFRAMEPIXEL 0x71044
1074-
1075-#define DSPACNTR 0x70180
1076-#define DSPBCNTR 0x71180
1077-#define DISPLAY_PLANE_ENABLE (1<<31)
1078-#define DISPLAY_PLANE_DISABLE 0
1079-#define DISPPLANE_GAMMA_ENABLE (1<<30)
1080-#define DISPPLANE_GAMMA_DISABLE 0
1081-#define DISPPLANE_PIXFORMAT_MASK (0xf<<26)
1082-#define DISPPLANE_8BPP (0x2<<26)
1083-#define DISPPLANE_15_16BPP (0x4<<26)
1084-#define DISPPLANE_16BPP (0x5<<26)
1085-#define DISPPLANE_32BPP_NO_ALPHA (0x6<<26)
1086-#define DISPPLANE_32BPP (0x7<<26)
1087-#define DISPPLANE_STEREO_ENABLE (1<<25)
1088-#define DISPPLANE_STEREO_DISABLE 0
1089-#define DISPPLANE_SEL_PIPE_MASK (1<<24)
1090-#define DISPPLANE_SEL_PIPE_A 0
1091-#define DISPPLANE_SEL_PIPE_B (1<<24)
1092-#define DISPPLANE_SRC_KEY_ENABLE (1<<22)
1093-#define DISPPLANE_SRC_KEY_DISABLE 0
1094-#define DISPPLANE_LINE_DOUBLE (1<<20)
1095-#define DISPPLANE_NO_LINE_DOUBLE 0
1096-#define DISPPLANE_STEREO_POLARITY_FIRST 0
1097-#define DISPPLANE_STEREO_POLARITY_SECOND (1<<18)
1098-/* plane B only */
1099-#define DISPPLANE_ALPHA_TRANS_ENABLE (1<<15)
1100-#define DISPPLANE_ALPHA_TRANS_DISABLE 0
1101-#define DISPPLANE_SPRITE_ABOVE_DISPLAYA 0
1102-#define DISPPLANE_SPRITE_ABOVE_OVERLAY (1)
1103-
1104-#define DSPABASE 0x70184
1105-#define DSPASTRIDE 0x70188
1106-
1107-#define DSPBBASE 0x71184
1108-#define DSPBADDR DSPBBASE
1109-#define DSPBSTRIDE 0x71188
1110-
1111-#define DSPAKEYVAL 0x70194
1112-#define DSPAKEYMASK 0x70198
1113-
1114-#define DSPAPOS 0x7018C /* reserved */
1115-#define DSPASIZE 0x70190
1116-#define DSPBPOS 0x7118C
1117-#define DSPBSIZE 0x71190
1118-
1119-#define DSPASURF 0x7019C
1120-#define DSPATILEOFF 0x701A4
1121-
1122-#define DSPBSURF 0x7119C
1123-#define DSPBTILEOFF 0x711A4
1124-
1125-#define VGACNTRL 0x71400
1126-# define VGA_DISP_DISABLE (1 << 31)
1127-# define VGA_2X_MODE (1 << 30)
1128-# define VGA_PIPE_B_SELECT (1 << 29)
1129-
1130-/*
1131- * Some BIOS scratch area registers. The 845 (and 830?) store the amount
1132- * of video memory available to the BIOS in SWF1.
1133- */
1134-
1135-#define SWF0 0x71410
1136-
1137-/*
1138- * 855 scratch registers.
1139- */
1140-#define SWF10 0x70410
1141-
1142-#define SWF30 0x72414
1143-
1144-/*
1145- * Overlay registers. These are overlay registers accessed via MMIO.
1146- * Those loaded via the overlay register page are defined in i830_video.c.
1147- */
1148-#define OVADD 0x30000
1149-
1150-#define DOVSTA 0x30008
1151-#define OC_BUF (0x3<<20)
1152+#define READ_HWSP(dev_priv, reg) (((volatile u32*)(dev_priv->hw_status_page))[reg])
1153+#define READ_BREADCRUMB(dev_priv) READ_HWSP(dev_priv, 5)
1154
1155-#define OGAMC5 0x30010
1156-#define OGAMC4 0x30014
1157-#define OGAMC3 0x30018
1158-#define OGAMC2 0x3001c
1159-#define OGAMC1 0x30020
1160-#define OGAMC0 0x30024
1161-/*
1162- * Palette registers
1163- */
1164-#define PALETTE_A 0x0a000
1165-#define PALETTE_B 0x0a800
1166+extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
1167
1168 #define IS_I830(dev) ((dev)->pci_device == 0x3577)
1169 #define IS_845G(dev) ((dev)->pci_device == 0x2562)
1170--- a/drivers/gpu/drm/i915/i915_irq.c
1171+++ b/drivers/gpu/drm/i915/i915_irq.c
1172@@ -31,10 +31,6 @@
1173 #include "i915_drm.h"
1174 #include "i915_drv.h"
1175
1176-#define USER_INT_FLAG (1<<1)
1177-#define VSYNC_PIPEB_FLAG (1<<5)
1178-#define VSYNC_PIPEA_FLAG (1<<7)
1179-
1180 #define MAX_NOPID ((u32)~0)
1181
1182 /**
1183@@ -236,40 +232,43 @@ irqreturn_t i915_driver_irq_handler(DRM_
1184 u16 temp;
1185 u32 pipea_stats, pipeb_stats;
1186
1187- pipea_stats = I915_READ(I915REG_PIPEASTAT);
1188- pipeb_stats = I915_READ(I915REG_PIPEBSTAT);
1189+ pipea_stats = I915_READ(PIPEASTAT);
1190+ pipeb_stats = I915_READ(PIPEBSTAT);
1191
1192- temp = I915_READ16(I915REG_INT_IDENTITY_R);
1193+ temp = I915_READ16(IIR);
1194
1195- temp &= (USER_INT_FLAG | VSYNC_PIPEA_FLAG | VSYNC_PIPEB_FLAG);
1196+ temp &= (I915_USER_INTERRUPT |
1197+ I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT |
1198+ I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT);
1199
1200 DRM_DEBUG("%s flag=%08x\n", __FUNCTION__, temp);
1201
1202 if (temp == 0)
1203 return IRQ_NONE;
1204
1205- I915_WRITE16(I915REG_INT_IDENTITY_R, temp);
1206- (void) I915_READ16(I915REG_INT_IDENTITY_R);
1207+ I915_WRITE16(IIR, temp);
1208+ (void) I915_READ16(IIR);
1209 DRM_READMEMORYBARRIER();
1210
1211 dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
1212
1213- if (temp & USER_INT_FLAG)
1214+ if (temp & I915_USER_INTERRUPT)
1215 DRM_WAKEUP(&dev_priv->irq_queue);
1216
1217- if (temp & (VSYNC_PIPEA_FLAG | VSYNC_PIPEB_FLAG)) {
1218+ if (temp & (I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT |
1219+ I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT)) {
1220 int vblank_pipe = dev_priv->vblank_pipe;
1221
1222 if ((vblank_pipe &
1223 (DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B))
1224 == (DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B)) {
1225- if (temp & VSYNC_PIPEA_FLAG)
1226+ if (temp & I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT)
1227 atomic_inc(&dev->vbl_received);
1228- if (temp & VSYNC_PIPEB_FLAG)
1229+ if (temp & I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT)
1230 atomic_inc(&dev->vbl_received2);
1231- } else if (((temp & VSYNC_PIPEA_FLAG) &&
1232+ } else if (((temp & I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT) &&
1233 (vblank_pipe & DRM_I915_VBLANK_PIPE_A)) ||
1234- ((temp & VSYNC_PIPEB_FLAG) &&
1235+ ((temp & I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT) &&
1236 (vblank_pipe & DRM_I915_VBLANK_PIPE_B)))
1237 atomic_inc(&dev->vbl_received);
1238
1239@@ -278,12 +277,12 @@ irqreturn_t i915_driver_irq_handler(DRM_
1240
1241 if (dev_priv->swaps_pending > 0)
1242 drm_locked_tasklet(dev, i915_vblank_tasklet);
1243- I915_WRITE(I915REG_PIPEASTAT,
1244+ I915_WRITE(PIPEASTAT,
1245 pipea_stats|I915_VBLANK_INTERRUPT_ENABLE|
1246- I915_VBLANK_CLEAR);
1247- I915_WRITE(I915REG_PIPEBSTAT,
1248+ PIPE_VBLANK_INTERRUPT_STATUS);
1249+ I915_WRITE(PIPEBSTAT,
1250 pipeb_stats|I915_VBLANK_INTERRUPT_ENABLE|
1251- I915_VBLANK_CLEAR);
1252+ PIPE_VBLANK_INTERRUPT_STATUS);
1253 }
1254
1255 return IRQ_HANDLED;
1256@@ -304,12 +303,12 @@ static int i915_emit_irq(struct drm_devi
1257 dev_priv->sarea_priv->last_enqueue = dev_priv->counter = 1;
1258
1259 BEGIN_LP_RING(6);
1260- OUT_RING(CMD_STORE_DWORD_IDX);
1261- OUT_RING(20);
1262+ OUT_RING(MI_STORE_DWORD_INDEX);
1263+ OUT_RING(5 << MI_STORE_DWORD_INDEX_SHIFT);
1264 OUT_RING(dev_priv->counter);
1265 OUT_RING(0);
1266 OUT_RING(0);
1267- OUT_RING(GFX_OP_USER_INTERRUPT);
1268+ OUT_RING(MI_USER_INTERRUPT);
1269 ADVANCE_LP_RING();
1270
1271 return dev_priv->counter;
1272@@ -421,11 +420,11 @@ static void i915_enable_interrupt (struc
1273
1274 flag = 0;
1275 if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_A)
1276- flag |= VSYNC_PIPEA_FLAG;
1277+ flag |= I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT;
1278 if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_B)
1279- flag |= VSYNC_PIPEB_FLAG;
1280+ flag |= I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
1281
1282- I915_WRITE16(I915REG_INT_ENABLE_R, USER_INT_FLAG | flag);
1283+ I915_WRITE16(IER, I915_USER_INTERRUPT | flag);
1284 }
1285
1286 /* Set the vblank monitor pipe
1287@@ -465,11 +464,11 @@ int i915_vblank_pipe_get(struct drm_devi
1288 return -EINVAL;
1289 }
1290
1291- flag = I915_READ(I915REG_INT_ENABLE_R);
1292+ flag = I915_READ(IER);
1293 pipe->pipe = 0;
1294- if (flag & VSYNC_PIPEA_FLAG)
1295+ if (flag & I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT)
1296 pipe->pipe |= DRM_I915_VBLANK_PIPE_A;
1297- if (flag & VSYNC_PIPEB_FLAG)
1298+ if (flag & I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT)
1299 pipe->pipe |= DRM_I915_VBLANK_PIPE_B;
1300
1301 return 0;
1302@@ -587,9 +586,9 @@ void i915_driver_irq_preinstall(struct d
1303 {
1304 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
1305
1306- I915_WRITE16(I915REG_HWSTAM, 0xfffe);
1307- I915_WRITE16(I915REG_INT_MASK_R, 0x0);
1308- I915_WRITE16(I915REG_INT_ENABLE_R, 0x0);
1309+ I915_WRITE16(HWSTAM, 0xfffe);
1310+ I915_WRITE16(IMR, 0x0);
1311+ I915_WRITE16(IER, 0x0);
1312 }
1313
1314 void i915_driver_irq_postinstall(struct drm_device * dev)
1315@@ -614,10 +613,10 @@ void i915_driver_irq_uninstall(struct dr
1316 if (!dev_priv)
1317 return;
1318
1319- I915_WRITE16(I915REG_HWSTAM, 0xffff);
1320- I915_WRITE16(I915REG_INT_MASK_R, 0xffff);
1321- I915_WRITE16(I915REG_INT_ENABLE_R, 0x0);
1322+ I915_WRITE16(HWSTAM, 0xffff);
1323+ I915_WRITE16(IMR, 0xffff);
1324+ I915_WRITE16(IER, 0x0);
1325
1326- temp = I915_READ16(I915REG_INT_IDENTITY_R);
1327- I915_WRITE16(I915REG_INT_IDENTITY_R, temp);
1328+ temp = I915_READ16(IIR);
1329+ I915_WRITE16(IIR, temp);
1330 }
1331--- /dev/null
1332+++ b/drivers/gpu/drm/i915/i915_reg.h
1333@@ -0,0 +1,1405 @@
1334+/* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
1335+ * All Rights Reserved.
1336+ *
1337+ * Permission is hereby granted, free of charge, to any person obtaining a
1338+ * copy of this software and associated documentation files (the
1339+ * "Software"), to deal in the Software without restriction, including
1340+ * without limitation the rights to use, copy, modify, merge, publish,
1341+ * distribute, sub license, and/or sell copies of the Software, and to
1342+ * permit persons to whom the Software is furnished to do so, subject to
1343+ * the following conditions:
1344+ *
1345+ * The above copyright notice and this permission notice (including the
1346+ * next paragraph) shall be included in all copies or substantial portions
1347+ * of the Software.
1348+ *
1349+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
1350+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
1351+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
1352+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
1353+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
1354+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
1355+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1356+ */
1357+
1358+#ifndef _I915_REG_H_
1359+#define _I915_REG_H_
1360+
1361+/* MCH MMIO space */
1362+/** 915-945 and GM965 MCH register controlling DRAM channel access */
1363+#define DCC 0x200
1364+#define DCC_ADDRESSING_MODE_SINGLE_CHANNEL (0 << 0)
1365+#define DCC_ADDRESSING_MODE_DUAL_CHANNEL_ASYMMETRIC (1 << 0)
1366+#define DCC_ADDRESSING_MODE_DUAL_CHANNEL_INTERLEAVED (2 << 0)
1367+#define DCC_ADDRESSING_MODE_MASK (3 << 0)
1368+#define DCC_CHANNEL_XOR_DISABLE (1 << 10)
1369+
1370+/** 965 MCH register controlling DRAM channel configuration */
1371+#define CHDECMISC 0x111
1372+#define CHDECMISC_FLEXMEMORY (1 << 1)
1373+
1374+/*
1375+ * The Bridge device's PCI config space has information about the
1376+ * fb aperture size and the amount of pre-reserved memory.
1377+ */
1378+#define INTEL_GMCH_CTRL 0x52
1379+#define INTEL_GMCH_ENABLED 0x4
1380+#define INTEL_GMCH_MEM_MASK 0x1
1381+#define INTEL_GMCH_MEM_64M 0x1
1382+#define INTEL_GMCH_MEM_128M 0
1383+
1384+#define INTEL_855_GMCH_GMS_MASK (0x7 << 4)
1385+#define INTEL_855_GMCH_GMS_DISABLED (0x0 << 4)
1386+#define INTEL_855_GMCH_GMS_STOLEN_1M (0x1 << 4)
1387+#define INTEL_855_GMCH_GMS_STOLEN_4M (0x2 << 4)
1388+#define INTEL_855_GMCH_GMS_STOLEN_8M (0x3 << 4)
1389+#define INTEL_855_GMCH_GMS_STOLEN_16M (0x4 << 4)
1390+#define INTEL_855_GMCH_GMS_STOLEN_32M (0x5 << 4)
1391+
1392+#define INTEL_915G_GMCH_GMS_STOLEN_48M (0x6 << 4)
1393+#define INTEL_915G_GMCH_GMS_STOLEN_64M (0x7 << 4)
1394+
1395+/* PCI config space */
1396+
1397+#define HPLLCC 0xc0 /* 855 only */
1398+#define GC_CLOCK_CONTROL_MASK (3 << 0)
1399+#define GC_CLOCK_133_200 (0 << 0)
1400+#define GC_CLOCK_100_200 (1 << 0)
1401+#define GC_CLOCK_100_133 (2 << 0)
1402+#define GC_CLOCK_166_250 (3 << 0)
1403+#define GCFGC 0xf0 /* 915+ only */
1404+#define GC_LOW_FREQUENCY_ENABLE (1 << 7)
1405+#define GC_DISPLAY_CLOCK_190_200_MHZ (0 << 4)
1406+#define GC_DISPLAY_CLOCK_333_MHZ (4 << 4)
1407+#define GC_DISPLAY_CLOCK_MASK (7 << 4)
1408+#define LBB 0xf4
1409+
1410+/* VGA stuff */
1411+
1412+#define VGA_ST01_MDA 0x3ba
1413+#define VGA_ST01_CGA 0x3da
1414+
1415+#define VGA_MSR_WRITE 0x3c2
1416+#define VGA_MSR_READ 0x3cc
1417+#define VGA_MSR_MEM_EN (1<<1)
1418+#define VGA_MSR_CGA_MODE (1<<0)
1419+
1420+#define VGA_SR_INDEX 0x3c4
1421+#define VGA_SR_DATA 0x3c5
1422+
1423+#define VGA_AR_INDEX 0x3c0
1424+#define VGA_AR_VID_EN (1<<5)
1425+#define VGA_AR_DATA_WRITE 0x3c0
1426+#define VGA_AR_DATA_READ 0x3c1
1427+
1428+#define VGA_GR_INDEX 0x3ce
1429+#define VGA_GR_DATA 0x3cf
1430+/* GR05 */
1431+#define VGA_GR_MEM_READ_MODE_SHIFT 3
1432+#define VGA_GR_MEM_READ_MODE_PLANE 1
1433+/* GR06 */
1434+#define VGA_GR_MEM_MODE_MASK 0xc
1435+#define VGA_GR_MEM_MODE_SHIFT 2
1436+#define VGA_GR_MEM_A0000_AFFFF 0
1437+#define VGA_GR_MEM_A0000_BFFFF 1
1438+#define VGA_GR_MEM_B0000_B7FFF 2
1439+#define VGA_GR_MEM_B0000_BFFFF 3
1440+
1441+#define VGA_DACMASK 0x3c6
1442+#define VGA_DACRX 0x3c7
1443+#define VGA_DACWX 0x3c8
1444+#define VGA_DACDATA 0x3c9
1445+
1446+#define VGA_CR_INDEX_MDA 0x3b4
1447+#define VGA_CR_DATA_MDA 0x3b5
1448+#define VGA_CR_INDEX_CGA 0x3d4
1449+#define VGA_CR_DATA_CGA 0x3d5
1450+
1451+/*
1452+ * Memory interface instructions used by the kernel
1453+ */
1454+#define MI_INSTR(opcode, flags) (((opcode) << 23) | (flags))
1455+
1456+#define MI_NOOP MI_INSTR(0, 0)
1457+#define MI_USER_INTERRUPT MI_INSTR(0x02, 0)
1458+#define MI_WAIT_FOR_EVENT MI_INSTR(0x03, 0)
1459+#define MI_WAIT_FOR_PLANE_B_FLIP (1<<6)
1460+#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2)
1461+#define MI_WAIT_FOR_PLANE_A_SCANLINES (1<<1)
1462+#define MI_FLUSH MI_INSTR(0x04, 0)
1463+#define MI_READ_FLUSH (1 << 0)
1464+#define MI_EXE_FLUSH (1 << 1)
1465+#define MI_NO_WRITE_FLUSH (1 << 2)
1466+#define MI_SCENE_COUNT (1 << 3) /* just increment scene count */
1467+#define MI_END_SCENE (1 << 4) /* flush binner and incr scene count */
1468+#define MI_BATCH_BUFFER_END MI_INSTR(0x0a, 0)
1469+#define MI_REPORT_HEAD MI_INSTR(0x07, 0)
1470+#define MI_LOAD_SCAN_LINES_INCL MI_INSTR(0x12, 0)
1471+#define MI_STORE_DWORD_IMM MI_INSTR(0x20, 1)
1472+#define MI_MEM_VIRTUAL (1 << 22) /* 965+ only */
1473+#define MI_STORE_DWORD_INDEX MI_INSTR(0x21, 1)
1474+#define MI_STORE_DWORD_INDEX_SHIFT 2
1475+#define MI_LOAD_REGISTER_IMM MI_INSTR(0x22, 1)
1476+#define MI_BATCH_BUFFER MI_INSTR(0x30, 1)
1477+#define MI_BATCH_NON_SECURE (1)
1478+#define MI_BATCH_NON_SECURE_I965 (1<<8)
1479+#define MI_BATCH_BUFFER_START MI_INSTR(0x31, 0)
1480+
1481+/*
1482+ * 3D instructions used by the kernel
1483+ */
1484+#define GFX_INSTR(opcode, flags) ((0x3 << 29) | ((opcode) << 24) | (flags))
1485+
1486+#define GFX_OP_RASTER_RULES ((0x3<<29)|(0x7<<24))
1487+#define GFX_OP_SCISSOR ((0x3<<29)|(0x1c<<24)|(0x10<<19))
1488+#define SC_UPDATE_SCISSOR (0x1<<1)
1489+#define SC_ENABLE_MASK (0x1<<0)
1490+#define SC_ENABLE (0x1<<0)
1491+#define GFX_OP_LOAD_INDIRECT ((0x3<<29)|(0x1d<<24)|(0x7<<16))
1492+#define GFX_OP_SCISSOR_INFO ((0x3<<29)|(0x1d<<24)|(0x81<<16)|(0x1))
1493+#define SCI_YMIN_MASK (0xffff<<16)
1494+#define SCI_XMIN_MASK (0xffff<<0)
1495+#define SCI_YMAX_MASK (0xffff<<16)
1496+#define SCI_XMAX_MASK (0xffff<<0)
1497+#define GFX_OP_SCISSOR_ENABLE ((0x3<<29)|(0x1c<<24)|(0x10<<19))
1498+#define GFX_OP_SCISSOR_RECT ((0x3<<29)|(0x1d<<24)|(0x81<<16)|1)
1499+#define GFX_OP_COLOR_FACTOR ((0x3<<29)|(0x1d<<24)|(0x1<<16)|0x0)
1500+#define GFX_OP_STIPPLE ((0x3<<29)|(0x1d<<24)|(0x83<<16))
1501+#define GFX_OP_MAP_INFO ((0x3<<29)|(0x1d<<24)|0x4)
1502+#define GFX_OP_DESTBUFFER_VARS ((0x3<<29)|(0x1d<<24)|(0x85<<16)|0x0)
1503+#define GFX_OP_DESTBUFFER_INFO ((0x3<<29)|(0x1d<<24)|(0x8e<<16)|1)
1504+#define GFX_OP_DRAWRECT_INFO ((0x3<<29)|(0x1d<<24)|(0x80<<16)|(0x3))
1505+#define GFX_OP_DRAWRECT_INFO_I965 ((0x7900<<16)|0x2)
1506+#define SRC_COPY_BLT_CMD ((2<<29)|(0x43<<22)|4)
1507+#define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6)
1508+#define XY_MONO_SRC_COPY_IMM_BLT ((2<<29)|(0x71<<22)|5)
1509+#define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21)
1510+#define XY_SRC_COPY_BLT_WRITE_RGB (1<<20)
1511+#define BLT_DEPTH_8 (0<<24)
1512+#define BLT_DEPTH_16_565 (1<<24)
1513+#define BLT_DEPTH_16_1555 (2<<24)
1514+#define BLT_DEPTH_32 (3<<24)
1515+#define BLT_ROP_GXCOPY (0xcc<<16)
1516+#define XY_SRC_COPY_BLT_SRC_TILED (1<<15) /* 965+ only */
1517+#define XY_SRC_COPY_BLT_DST_TILED (1<<11) /* 965+ only */
1518+#define CMD_OP_DISPLAYBUFFER_INFO ((0x0<<29)|(0x14<<23)|2)
1519+#define ASYNC_FLIP (1<<22)
1520+#define DISPLAY_PLANE_A (0<<20)
1521+#define DISPLAY_PLANE_B (1<<20)
1522+
1523+/*
1524+ * Instruction and interrupt control regs
1525+ */
1526+
1527+#define PRB0_TAIL 0x02030
1528+#define PRB0_HEAD 0x02034
1529+#define PRB0_START 0x02038
1530+#define PRB0_CTL 0x0203c
1531+#define TAIL_ADDR 0x001FFFF8
1532+#define HEAD_WRAP_COUNT 0xFFE00000
1533+#define HEAD_WRAP_ONE 0x00200000
1534+#define HEAD_ADDR 0x001FFFFC
1535+#define RING_NR_PAGES 0x001FF000
1536+#define RING_REPORT_MASK 0x00000006
1537+#define RING_REPORT_64K 0x00000002
1538+#define RING_REPORT_128K 0x00000004
1539+#define RING_NO_REPORT 0x00000000
1540+#define RING_VALID_MASK 0x00000001
1541+#define RING_VALID 0x00000001
1542+#define RING_INVALID 0x00000000
1543+#define PRB1_TAIL 0x02040 /* 915+ only */
1544+#define PRB1_HEAD 0x02044 /* 915+ only */
1545+#define PRB1_START 0x02048 /* 915+ only */
1546+#define PRB1_CTL 0x0204c /* 915+ only */
1547+#define ACTHD_I965 0x02074
1548+#define HWS_PGA 0x02080
1549+#define HWS_ADDRESS_MASK 0xfffff000
1550+#define HWS_START_ADDRESS_SHIFT 4
1551+#define IPEIR 0x02088
1552+#define NOPID 0x02094
1553+#define HWSTAM 0x02098
1554+#define SCPD0 0x0209c /* 915+ only */
1555+#define IER 0x020a0
1556+#define IIR 0x020a4
1557+#define IMR 0x020a8
1558+#define ISR 0x020ac
1559+#define I915_PIPE_CONTROL_NOTIFY_INTERRUPT (1<<18)
1560+#define I915_DISPLAY_PORT_INTERRUPT (1<<17)
1561+#define I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT (1<<15)
1562+#define I915_GMCH_THERMAL_SENSOR_EVENT_INTERRUPT (1<<14)
1563+#define I915_HWB_OOM_INTERRUPT (1<<13)
1564+#define I915_SYNC_STATUS_INTERRUPT (1<<12)
1565+#define I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT (1<<11)
1566+#define I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT (1<<10)
1567+#define I915_OVERLAY_PLANE_FLIP_PENDING_INTERRUPT (1<<9)
1568+#define I915_DISPLAY_PLANE_C_FLIP_PENDING_INTERRUPT (1<<8)
1569+#define I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT (1<<7)
1570+#define I915_DISPLAY_PIPE_A_EVENT_INTERRUPT (1<<6)
1571+#define I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT (1<<5)
1572+#define I915_DISPLAY_PIPE_B_EVENT_INTERRUPT (1<<4)
1573+#define I915_DEBUG_INTERRUPT (1<<2)
1574+#define I915_USER_INTERRUPT (1<<1)
1575+#define I915_ASLE_INTERRUPT (1<<0)
1576+#define EIR 0x020b0
1577+#define EMR 0x020b4
1578+#define ESR 0x020b8
1579+#define INSTPM 0x020c0
1580+#define ACTHD 0x020c8
1581+#define FW_BLC 0x020d8
1582+#define FW_BLC_SELF 0x020e0 /* 915+ only */
1583+#define MI_ARB_STATE 0x020e4 /* 915+ only */
1584+#define CACHE_MODE_0 0x02120 /* 915+ only */
1585+#define CM0_MASK_SHIFT 16
1586+#define CM0_IZ_OPT_DISABLE (1<<6)
1587+#define CM0_ZR_OPT_DISABLE (1<<5)
1588+#define CM0_DEPTH_EVICT_DISABLE (1<<4)
1589+#define CM0_COLOR_EVICT_DISABLE (1<<3)
1590+#define CM0_DEPTH_WRITE_DISABLE (1<<1)
1591+#define CM0_RC_OP_FLUSH_DISABLE (1<<0)
1592+#define GFX_FLSH_CNTL 0x02170 /* 915+ only */
1593+
1594+/*
1595+ * Framebuffer compression (915+ only)
1596+ */
1597+
1598+#define FBC_CFB_BASE 0x03200 /* 4k page aligned */
1599+#define FBC_LL_BASE 0x03204 /* 4k page aligned */
1600+#define FBC_CONTROL 0x03208
1601+#define FBC_CTL_EN (1<<31)
1602+#define FBC_CTL_PERIODIC (1<<30)
1603+#define FBC_CTL_INTERVAL_SHIFT (16)
1604+#define FBC_CTL_UNCOMPRESSIBLE (1<<14)
1605+#define FBC_CTL_STRIDE_SHIFT (5)
1606+#define FBC_CTL_FENCENO (1<<0)
1607+#define FBC_COMMAND 0x0320c
1608+#define FBC_CMD_COMPRESS (1<<0)
1609+#define FBC_STATUS 0x03210
1610+#define FBC_STAT_COMPRESSING (1<<31)
1611+#define FBC_STAT_COMPRESSED (1<<30)
1612+#define FBC_STAT_MODIFIED (1<<29)
1613+#define FBC_STAT_CURRENT_LINE (1<<0)
1614+#define FBC_CONTROL2 0x03214
1615+#define FBC_CTL_FENCE_DBL (0<<4)
1616+#define FBC_CTL_IDLE_IMM (0<<2)
1617+#define FBC_CTL_IDLE_FULL (1<<2)
1618+#define FBC_CTL_IDLE_LINE (2<<2)
1619+#define FBC_CTL_IDLE_DEBUG (3<<2)
1620+#define FBC_CTL_CPU_FENCE (1<<1)
1621+#define FBC_CTL_PLANEA (0<<0)
1622+#define FBC_CTL_PLANEB (1<<0)
1623+#define FBC_FENCE_OFF 0x0321b
1624+
1625+#define FBC_LL_SIZE (1536)
1626+
1627+/*
1628+ * GPIO regs
1629+ */
1630+#define GPIOA 0x5010
1631+#define GPIOB 0x5014
1632+#define GPIOC 0x5018
1633+#define GPIOD 0x501c
1634+#define GPIOE 0x5020
1635+#define GPIOF 0x5024
1636+#define GPIOG 0x5028
1637+#define GPIOH 0x502c
1638+# define GPIO_CLOCK_DIR_MASK (1 << 0)
1639+# define GPIO_CLOCK_DIR_IN (0 << 1)
1640+# define GPIO_CLOCK_DIR_OUT (1 << 1)
1641+# define GPIO_CLOCK_VAL_MASK (1 << 2)
1642+# define GPIO_CLOCK_VAL_OUT (1 << 3)
1643+# define GPIO_CLOCK_VAL_IN (1 << 4)
1644+# define GPIO_CLOCK_PULLUP_DISABLE (1 << 5)
1645+# define GPIO_DATA_DIR_MASK (1 << 8)
1646+# define GPIO_DATA_DIR_IN (0 << 9)
1647+# define GPIO_DATA_DIR_OUT (1 << 9)
1648+# define GPIO_DATA_VAL_MASK (1 << 10)
1649+# define GPIO_DATA_VAL_OUT (1 << 11)
1650+# define GPIO_DATA_VAL_IN (1 << 12)
1651+# define GPIO_DATA_PULLUP_DISABLE (1 << 13)
1652+
1653+/*
1654+ * Clock control & power management
1655+ */
1656+
1657+#define VGA0 0x6000
1658+#define VGA1 0x6004
1659+#define VGA_PD 0x6010
1660+#define VGA0_PD_P2_DIV_4 (1 << 7)
1661+#define VGA0_PD_P1_DIV_2 (1 << 5)
1662+#define VGA0_PD_P1_SHIFT 0
1663+#define VGA0_PD_P1_MASK (0x1f << 0)
1664+#define VGA1_PD_P2_DIV_4 (1 << 15)
1665+#define VGA1_PD_P1_DIV_2 (1 << 13)
1666+#define VGA1_PD_P1_SHIFT 8
1667+#define VGA1_PD_P1_MASK (0x1f << 8)
1668+#define DPLL_A 0x06014
1669+#define DPLL_B 0x06018
1670+#define DPLL_VCO_ENABLE (1 << 31)
1671+#define DPLL_DVO_HIGH_SPEED (1 << 30)
1672+#define DPLL_SYNCLOCK_ENABLE (1 << 29)
1673+#define DPLL_VGA_MODE_DIS (1 << 28)
1674+#define DPLLB_MODE_DAC_SERIAL (1 << 26) /* i915 */
1675+#define DPLLB_MODE_LVDS (2 << 26) /* i915 */
1676+#define DPLL_MODE_MASK (3 << 26)
1677+#define DPLL_DAC_SERIAL_P2_CLOCK_DIV_10 (0 << 24) /* i915 */
1678+#define DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 (1 << 24) /* i915 */
1679+#define DPLLB_LVDS_P2_CLOCK_DIV_14 (0 << 24) /* i915 */
1680+#define DPLLB_LVDS_P2_CLOCK_DIV_7 (1 << 24) /* i915 */
1681+#define DPLL_P2_CLOCK_DIV_MASK 0x03000000 /* i915 */
1682+#define DPLL_FPA01_P1_POST_DIV_MASK 0x00ff0000 /* i915 */
1683+
1684+#define I915_FIFO_UNDERRUN_STATUS (1UL<<31)
1685+#define I915_CRC_ERROR_ENABLE (1UL<<29)
1686+#define I915_CRC_DONE_ENABLE (1UL<<28)
1687+#define I915_GMBUS_EVENT_ENABLE (1UL<<27)
1688+#define I915_VSYNC_INTERRUPT_ENABLE (1UL<<25)
1689+#define I915_DISPLAY_LINE_COMPARE_ENABLE (1UL<<24)
1690+#define I915_DPST_EVENT_ENABLE (1UL<<23)
1691+#define I915_LEGACY_BLC_EVENT_ENABLE (1UL<<22)
1692+#define I915_ODD_FIELD_INTERRUPT_ENABLE (1UL<<21)
1693+#define I915_EVEN_FIELD_INTERRUPT_ENABLE (1UL<<20)
1694+#define I915_START_VBLANK_INTERRUPT_ENABLE (1UL<<18) /* 965 or later */
1695+#define I915_VBLANK_INTERRUPT_ENABLE (1UL<<17)
1696+#define I915_OVERLAY_UPDATED_ENABLE (1UL<<16)
1697+#define I915_CRC_ERROR_INTERRUPT_STATUS (1UL<<13)
1698+#define I915_CRC_DONE_INTERRUPT_STATUS (1UL<<12)
1699+#define I915_GMBUS_INTERRUPT_STATUS (1UL<<11)
1700+#define I915_VSYNC_INTERRUPT_STATUS (1UL<<9)
1701+#define I915_DISPLAY_LINE_COMPARE_STATUS (1UL<<8)
1702+#define I915_DPST_EVENT_STATUS (1UL<<7)
1703+#define I915_LEGACY_BLC_EVENT_STATUS (1UL<<6)
1704+#define I915_ODD_FIELD_INTERRUPT_STATUS (1UL<<5)
1705+#define I915_EVEN_FIELD_INTERRUPT_STATUS (1UL<<4)
1706+#define I915_START_VBLANK_INTERRUPT_STATUS (1UL<<2) /* 965 or later */
1707+#define I915_VBLANK_INTERRUPT_STATUS (1UL<<1)
1708+#define I915_OVERLAY_UPDATED_STATUS (1UL<<0)
1709+
1710+#define SRX_INDEX 0x3c4
1711+#define SRX_DATA 0x3c5
1712+#define SR01 1
1713+#define SR01_SCREEN_OFF (1<<5)
1714+
1715+#define PPCR 0x61204
1716+#define PPCR_ON (1<<0)
1717+
1718+#define DVOB 0x61140
1719+#define DVOB_ON (1<<31)
1720+#define DVOC 0x61160
1721+#define DVOC_ON (1<<31)
1722+#define LVDS 0x61180
1723+#define LVDS_ON (1<<31)
1724+
1725+#define ADPA 0x61100
1726+#define ADPA_DPMS_MASK (~(3<<10))
1727+#define ADPA_DPMS_ON (0<<10)
1728+#define ADPA_DPMS_SUSPEND (1<<10)
1729+#define ADPA_DPMS_STANDBY (2<<10)
1730+#define ADPA_DPMS_OFF (3<<10)
1731+
1732+#define RING_TAIL 0x00
1733+#define TAIL_ADDR 0x001FFFF8
1734+#define RING_HEAD 0x04
1735+#define HEAD_WRAP_COUNT 0xFFE00000
1736+#define HEAD_WRAP_ONE 0x00200000
1737+#define HEAD_ADDR 0x001FFFFC
1738+#define RING_START 0x08
1739+#define START_ADDR 0xFFFFF000
1740+#define RING_LEN 0x0C
1741+#define RING_NR_PAGES 0x001FF000
1742+#define RING_REPORT_MASK 0x00000006
1743+#define RING_REPORT_64K 0x00000002
1744+#define RING_REPORT_128K 0x00000004
1745+#define RING_NO_REPORT 0x00000000
1746+#define RING_VALID_MASK 0x00000001
1747+#define RING_VALID 0x00000001
1748+#define RING_INVALID 0x00000000
1749+
1750+/* Scratch pad debug 0 reg:
1751+ */
1752+#define DPLL_FPA01_P1_POST_DIV_MASK_I830 0x001f0000
1753+/*
1754+ * The i830 generation, in LVDS mode, defines P1 as the bit number set within
1755+ * this field (only one bit may be set).
1756+ */
1757+#define DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS 0x003f0000
1758+#define DPLL_FPA01_P1_POST_DIV_SHIFT 16
1759+/* i830, required in DVO non-gang */
1760+#define PLL_P2_DIVIDE_BY_4 (1 << 23)
1761+#define PLL_P1_DIVIDE_BY_TWO (1 << 21) /* i830 */
1762+#define PLL_REF_INPUT_DREFCLK (0 << 13)
1763+#define PLL_REF_INPUT_TVCLKINA (1 << 13) /* i830 */
1764+#define PLL_REF_INPUT_TVCLKINBC (2 << 13) /* SDVO TVCLKIN */
1765+#define PLLB_REF_INPUT_SPREADSPECTRUMIN (3 << 13)
1766+#define PLL_REF_INPUT_MASK (3 << 13)
1767+#define PLL_LOAD_PULSE_PHASE_SHIFT 9
1768+/*
1769+ * Parallel to Serial Load Pulse phase selection.
1770+ * Selects the phase for the 10X DPLL clock for the PCIe
1771+ * digital display port. The range is 4 to 13; 10 or more
1772+ * is just a flip delay. The default is 6
1773+ */
1774+#define PLL_LOAD_PULSE_PHASE_MASK (0xf << PLL_LOAD_PULSE_PHASE_SHIFT)
1775+#define DISPLAY_RATE_SELECT_FPA1 (1 << 8)
1776+/*
1777+ * SDVO multiplier for 945G/GM. Not used on 965.
1778+ */
1779+#define SDVO_MULTIPLIER_MASK 0x000000ff
1780+#define SDVO_MULTIPLIER_SHIFT_HIRES 4
1781+#define SDVO_MULTIPLIER_SHIFT_VGA 0
1782+#define DPLL_A_MD 0x0601c /* 965+ only */
1783+/*
1784+ * UDI pixel divider, controlling how many pixels are stuffed into a packet.
1785+ *
1786+ * Value is pixels minus 1. Must be set to 1 pixel for SDVO.
1787+ */
1788+#define DPLL_MD_UDI_DIVIDER_MASK 0x3f000000
1789+#define DPLL_MD_UDI_DIVIDER_SHIFT 24
1790+/* UDI pixel divider for VGA, same as DPLL_MD_UDI_DIVIDER_MASK. */
1791+#define DPLL_MD_VGA_UDI_DIVIDER_MASK 0x003f0000
1792+#define DPLL_MD_VGA_UDI_DIVIDER_SHIFT 16
1793+/*
1794+ * SDVO/UDI pixel multiplier.
1795+ *
1796+ * SDVO requires that the bus clock rate be between 1 and 2 Ghz, and the bus
1797+ * clock rate is 10 times the DPLL clock. At low resolution/refresh rate
1798+ * modes, the bus rate would be below the limits, so SDVO allows for stuffing
1799+ * dummy bytes in the datastream at an increased clock rate, with both sides of
1800+ * the link knowing how many bytes are fill.
1801+ *
1802+ * So, for a mode with a dotclock of 65Mhz, we would want to double the clock
1803+ * rate to 130Mhz to get a bus rate of 1.30Ghz. The DPLL clock rate would be
1804+ * set to 130Mhz, and the SDVO multiplier set to 2x in this register and
1805+ * through an SDVO command.
1806+ *
1807+ * This register field has values of multiplication factor minus 1, with
1808+ * a maximum multiplier of 5 for SDVO.
1809+ */
1810+#define DPLL_MD_UDI_MULTIPLIER_MASK 0x00003f00
1811+#define DPLL_MD_UDI_MULTIPLIER_SHIFT 8
1812+/*
1813+ * SDVO/UDI pixel multiplier for VGA, same as DPLL_MD_UDI_MULTIPLIER_MASK.
1814+ * This best be set to the default value (3) or the CRT won't work. No,
1815+ * I don't entirely understand what this does...
1816+ */
1817+#define DPLL_MD_VGA_UDI_MULTIPLIER_MASK 0x0000003f
1818+#define DPLL_MD_VGA_UDI_MULTIPLIER_SHIFT 0
1819+#define DPLL_B_MD 0x06020 /* 965+ only */
1820+#define FPA0 0x06040
1821+#define FPA1 0x06044
1822+#define FPB0 0x06048
1823+#define FPB1 0x0604c
1824+#define FP_N_DIV_MASK 0x003f0000
1825+#define FP_N_DIV_SHIFT 16
1826+#define FP_M1_DIV_MASK 0x00003f00
1827+#define FP_M1_DIV_SHIFT 8
1828+#define FP_M2_DIV_MASK 0x0000003f
1829+#define FP_M2_DIV_SHIFT 0
1830+#define DPLL_TEST 0x606c
1831+#define DPLLB_TEST_SDVO_DIV_1 (0 << 22)
1832+#define DPLLB_TEST_SDVO_DIV_2 (1 << 22)
1833+#define DPLLB_TEST_SDVO_DIV_4 (2 << 22)
1834+#define DPLLB_TEST_SDVO_DIV_MASK (3 << 22)
1835+#define DPLLB_TEST_N_BYPASS (1 << 19)
1836+#define DPLLB_TEST_M_BYPASS (1 << 18)
1837+#define DPLLB_INPUT_BUFFER_ENABLE (1 << 16)
1838+#define DPLLA_TEST_N_BYPASS (1 << 3)
1839+#define DPLLA_TEST_M_BYPASS (1 << 2)
1840+#define DPLLA_INPUT_BUFFER_ENABLE (1 << 0)
1841+#define D_STATE 0x6104
1842+#define CG_2D_DIS 0x6200
1843+#define CG_3D_DIS 0x6204
1844+
1845+/*
1846+ * Palette regs
1847+ */
1848+
1849+#define PALETTE_A 0x0a000
1850+#define PALETTE_B 0x0a800
1851+
1852+/*
1853+ * Overlay regs
1854+ */
1855+
1856+#define OVADD 0x30000
1857+#define DOVSTA 0x30008
1858+#define OC_BUF (0x3<<20)
1859+#define OGAMC5 0x30010
1860+#define OGAMC4 0x30014
1861+#define OGAMC3 0x30018
1862+#define OGAMC2 0x3001c
1863+#define OGAMC1 0x30020
1864+#define OGAMC0 0x30024
1865+
1866+/*
1867+ * Display engine regs
1868+ */
1869+
1870+/* Pipe A timing regs */
1871+#define HTOTAL_A 0x60000
1872+#define HBLANK_A 0x60004
1873+#define HSYNC_A 0x60008
1874+#define VTOTAL_A 0x6000c
1875+#define VBLANK_A 0x60010
1876+#define VSYNC_A 0x60014
1877+#define PIPEASRC 0x6001c
1878+#define BCLRPAT_A 0x60020
1879+
1880+/* Pipe B timing regs */
1881+#define HTOTAL_B 0x61000
1882+#define HBLANK_B 0x61004
1883+#define HSYNC_B 0x61008
1884+#define VTOTAL_B 0x6100c
1885+#define VBLANK_B 0x61010
1886+#define VSYNC_B 0x61014
1887+#define PIPEBSRC 0x6101c
1888+#define BCLRPAT_B 0x61020
1889+
1890+/* VGA port control */
1891+#define ADPA 0x61100
1892+#define ADPA_DAC_ENABLE (1<<31)
1893+#define ADPA_DAC_DISABLE 0
1894+#define ADPA_PIPE_SELECT_MASK (1<<30)
1895+#define ADPA_PIPE_A_SELECT 0
1896+#define ADPA_PIPE_B_SELECT (1<<30)
1897+#define ADPA_USE_VGA_HVPOLARITY (1<<15)
1898+#define ADPA_SETS_HVPOLARITY 0
1899+#define ADPA_VSYNC_CNTL_DISABLE (1<<11)
1900+#define ADPA_VSYNC_CNTL_ENABLE 0
1901+#define ADPA_HSYNC_CNTL_DISABLE (1<<10)
1902+#define ADPA_HSYNC_CNTL_ENABLE 0
1903+#define ADPA_VSYNC_ACTIVE_HIGH (1<<4)
1904+#define ADPA_VSYNC_ACTIVE_LOW 0
1905+#define ADPA_HSYNC_ACTIVE_HIGH (1<<3)
1906+#define ADPA_HSYNC_ACTIVE_LOW 0
1907+#define ADPA_DPMS_MASK (~(3<<10))
1908+#define ADPA_DPMS_ON (0<<10)
1909+#define ADPA_DPMS_SUSPEND (1<<10)
1910+#define ADPA_DPMS_STANDBY (2<<10)
1911+#define ADPA_DPMS_OFF (3<<10)
1912+
1913+/* Hotplug control (945+ only) */
1914+#define PORT_HOTPLUG_EN 0x61110
1915+#define SDVOB_HOTPLUG_INT_EN (1 << 26)
1916+#define SDVOC_HOTPLUG_INT_EN (1 << 25)
1917+#define TV_HOTPLUG_INT_EN (1 << 18)
1918+#define CRT_HOTPLUG_INT_EN (1 << 9)
1919+#define CRT_HOTPLUG_FORCE_DETECT (1 << 3)
1920+
1921+#define PORT_HOTPLUG_STAT 0x61114
1922+#define CRT_HOTPLUG_INT_STATUS (1 << 11)
1923+#define TV_HOTPLUG_INT_STATUS (1 << 10)
1924+#define CRT_HOTPLUG_MONITOR_MASK (3 << 8)
1925+#define CRT_HOTPLUG_MONITOR_COLOR (3 << 8)
1926+#define CRT_HOTPLUG_MONITOR_MONO (2 << 8)
1927+#define CRT_HOTPLUG_MONITOR_NONE (0 << 8)
1928+#define SDVOC_HOTPLUG_INT_STATUS (1 << 7)
1929+#define SDVOB_HOTPLUG_INT_STATUS (1 << 6)
1930+
1931+/* SDVO port control */
1932+#define SDVOB 0x61140
1933+#define SDVOC 0x61160
1934+#define SDVO_ENABLE (1 << 31)
1935+#define SDVO_PIPE_B_SELECT (1 << 30)
1936+#define SDVO_STALL_SELECT (1 << 29)
1937+#define SDVO_INTERRUPT_ENABLE (1 << 26)
1938+/**
1939+ * 915G/GM SDVO pixel multiplier.
1940+ *
1941+ * Programmed value is multiplier - 1, up to 5x.
1942+ *
1943+ * \sa DPLL_MD_UDI_MULTIPLIER_MASK
1944+ */
1945+#define SDVO_PORT_MULTIPLY_MASK (7 << 23)
1946+#define SDVO_PORT_MULTIPLY_SHIFT 23
1947+#define SDVO_PHASE_SELECT_MASK (15 << 19)
1948+#define SDVO_PHASE_SELECT_DEFAULT (6 << 19)
1949+#define SDVO_CLOCK_OUTPUT_INVERT (1 << 18)
1950+#define SDVOC_GANG_MODE (1 << 16)
1951+#define SDVO_BORDER_ENABLE (1 << 7)
1952+#define SDVOB_PCIE_CONCURRENCY (1 << 3)
1953+#define SDVO_DETECTED (1 << 2)
1954+/* Bits to be preserved when writing */
1955+#define SDVOB_PRESERVE_MASK ((1 << 17) | (1 << 16) | (1 << 14) | (1 << 26))
1956+#define SDVOC_PRESERVE_MASK ((1 << 17) | (1 << 26))
1957+
1958+/* DVO port control */
1959+#define DVOA 0x61120
1960+#define DVOB 0x61140
1961+#define DVOC 0x61160
1962+#define DVO_ENABLE (1 << 31)
1963+#define DVO_PIPE_B_SELECT (1 << 30)
1964+#define DVO_PIPE_STALL_UNUSED (0 << 28)
1965+#define DVO_PIPE_STALL (1 << 28)
1966+#define DVO_PIPE_STALL_TV (2 << 28)
1967+#define DVO_PIPE_STALL_MASK (3 << 28)
1968+#define DVO_USE_VGA_SYNC (1 << 15)
1969+#define DVO_DATA_ORDER_I740 (0 << 14)
1970+#define DVO_DATA_ORDER_FP (1 << 14)
1971+#define DVO_VSYNC_DISABLE (1 << 11)
1972+#define DVO_HSYNC_DISABLE (1 << 10)
1973+#define DVO_VSYNC_TRISTATE (1 << 9)
1974+#define DVO_HSYNC_TRISTATE (1 << 8)
1975+#define DVO_BORDER_ENABLE (1 << 7)
1976+#define DVO_DATA_ORDER_GBRG (1 << 6)
1977+#define DVO_DATA_ORDER_RGGB (0 << 6)
1978+#define DVO_DATA_ORDER_GBRG_ERRATA (0 << 6)
1979+#define DVO_DATA_ORDER_RGGB_ERRATA (1 << 6)
1980+#define DVO_VSYNC_ACTIVE_HIGH (1 << 4)
1981+#define DVO_HSYNC_ACTIVE_HIGH (1 << 3)
1982+#define DVO_BLANK_ACTIVE_HIGH (1 << 2)
1983+#define DVO_OUTPUT_CSTATE_PIXELS (1 << 1) /* SDG only */
1984+#define DVO_OUTPUT_SOURCE_SIZE_PIXELS (1 << 0) /* SDG only */
1985+#define DVO_PRESERVE_MASK (0x7<<24)
1986+#define DVOA_SRCDIM 0x61124
1987+#define DVOB_SRCDIM 0x61144
1988+#define DVOC_SRCDIM 0x61164
1989+#define DVO_SRCDIM_HORIZONTAL_SHIFT 12
1990+#define DVO_SRCDIM_VERTICAL_SHIFT 0
1991+
1992+/* LVDS port control */
1993+#define LVDS 0x61180
1994+/*
1995+ * Enables the LVDS port. This bit must be set before DPLLs are enabled, as
1996+ * the DPLL semantics change when the LVDS is assigned to that pipe.
1997+ */
1998+#define LVDS_PORT_EN (1 << 31)
1999+/* Selects pipe B for LVDS data. Must be set on pre-965. */
2000+#define LVDS_PIPEB_SELECT (1 << 30)
2001+/*
2002+ * Enables the A0-A2 data pairs and CLKA, containing 18 bits of color data per
2003+ * pixel.
2004+ */
2005+#define LVDS_A0A2_CLKA_POWER_MASK (3 << 8)
2006+#define LVDS_A0A2_CLKA_POWER_DOWN (0 << 8)
2007+#define LVDS_A0A2_CLKA_POWER_UP (3 << 8)
2008+/*
2009+ * Controls the A3 data pair, which contains the additional LSBs for 24 bit
2010+ * mode. Only enabled if LVDS_A0A2_CLKA_POWER_UP also indicates it should be
2011+ * on.
2012+ */
2013+#define LVDS_A3_POWER_MASK (3 << 6)
2014+#define LVDS_A3_POWER_DOWN (0 << 6)
2015+#define LVDS_A3_POWER_UP (3 << 6)
2016+/*
2017+ * Controls the CLKB pair. This should only be set when LVDS_B0B3_POWER_UP
2018+ * is set.
2019+ */
2020+#define LVDS_CLKB_POWER_MASK (3 << 4)
2021+#define LVDS_CLKB_POWER_DOWN (0 << 4)
2022+#define LVDS_CLKB_POWER_UP (3 << 4)
2023+/*
2024+ * Controls the B0-B3 data pairs. This must be set to match the DPLL p2
2025+ * setting for whether we are in dual-channel mode. The B3 pair will
2026+ * additionally only be powered up when LVDS_A3_POWER_UP is set.
2027+ */
2028+#define LVDS_B0B3_POWER_MASK (3 << 2)
2029+#define LVDS_B0B3_POWER_DOWN (0 << 2)
2030+#define LVDS_B0B3_POWER_UP (3 << 2)
2031+
2032+/* Panel power sequencing */
2033+#define PP_STATUS 0x61200
2034+#define PP_ON (1 << 31)
2035+/*
2036+ * Indicates that all dependencies of the panel are on:
2037+ *
2038+ * - PLL enabled
2039+ * - pipe enabled
2040+ * - LVDS/DVOB/DVOC on
2041+ */
2042+#define PP_READY (1 << 30)
2043+#define PP_SEQUENCE_NONE (0 << 28)
2044+#define PP_SEQUENCE_ON (1 << 28)
2045+#define PP_SEQUENCE_OFF (2 << 28)
2046+#define PP_SEQUENCE_MASK 0x30000000
2047+#define PP_CONTROL 0x61204
2048+#define POWER_TARGET_ON (1 << 0)
2049+#define PP_ON_DELAYS 0x61208
2050+#define PP_OFF_DELAYS 0x6120c
2051+#define PP_DIVISOR 0x61210
2052+
2053+/* Panel fitting */
2054+#define PFIT_CONTROL 0x61230
2055+#define PFIT_ENABLE (1 << 31)
2056+#define PFIT_PIPE_MASK (3 << 29)
2057+#define PFIT_PIPE_SHIFT 29
2058+#define VERT_INTERP_DISABLE (0 << 10)
2059+#define VERT_INTERP_BILINEAR (1 << 10)
2060+#define VERT_INTERP_MASK (3 << 10)
2061+#define VERT_AUTO_SCALE (1 << 9)
2062+#define HORIZ_INTERP_DISABLE (0 << 6)
2063+#define HORIZ_INTERP_BILINEAR (1 << 6)
2064+#define HORIZ_INTERP_MASK (3 << 6)
2065+#define HORIZ_AUTO_SCALE (1 << 5)
2066+#define PANEL_8TO6_DITHER_ENABLE (1 << 3)
2067+#define PFIT_PGM_RATIOS 0x61234
2068+#define PFIT_VERT_SCALE_MASK 0xfff00000
2069+#define PFIT_HORIZ_SCALE_MASK 0x0000fff0
2070+#define PFIT_AUTO_RATIOS 0x61238
2071+
2072+/* Backlight control */
2073+#define BLC_PWM_CTL 0x61254
2074+#define BACKLIGHT_MODULATION_FREQ_SHIFT (17)
2075+#define BLC_PWM_CTL2 0x61250 /* 965+ only */
2076+/*
2077+ * This is the most significant 15 bits of the number of backlight cycles in a
2078+ * complete cycle of the modulated backlight control.
2079+ *
2080+ * The actual value is this field multiplied by two.
2081+ */
2082+#define BACKLIGHT_MODULATION_FREQ_MASK (0x7fff << 17)
2083+#define BLM_LEGACY_MODE (1 << 16)
2084+/*
2085+ * This is the number of cycles out of the backlight modulation cycle for which
2086+ * the backlight is on.
2087+ *
2088+ * This field must be no greater than the number of cycles in the complete
2089+ * backlight modulation cycle.
2090+ */
2091+#define BACKLIGHT_DUTY_CYCLE_SHIFT (0)
2092+#define BACKLIGHT_DUTY_CYCLE_MASK (0xffff)
2093+
2094+/* TV port control */
2095+#define TV_CTL 0x68000
2096+/** Enables the TV encoder */
2097+# define TV_ENC_ENABLE (1 << 31)
2098+/** Sources the TV encoder input from pipe B instead of A. */
2099+# define TV_ENC_PIPEB_SELECT (1 << 30)
2100+/** Outputs composite video (DAC A only) */
2101+# define TV_ENC_OUTPUT_COMPOSITE (0 << 28)
2102+/** Outputs SVideo video (DAC B/C) */
2103+# define TV_ENC_OUTPUT_SVIDEO (1 << 28)
2104+/** Outputs Component video (DAC A/B/C) */
2105+# define TV_ENC_OUTPUT_COMPONENT (2 << 28)
2106+/** Outputs Composite and SVideo (DAC A/B/C) */
2107+# define TV_ENC_OUTPUT_SVIDEO_COMPOSITE (3 << 28)
2108+# define TV_TRILEVEL_SYNC (1 << 21)
2109+/** Enables slow sync generation (945GM only) */
2110+# define TV_SLOW_SYNC (1 << 20)
2111+/** Selects 4x oversampling for 480i and 576p */
2112+# define TV_OVERSAMPLE_4X (0 << 18)
2113+/** Selects 2x oversampling for 720p and 1080i */
2114+# define TV_OVERSAMPLE_2X (1 << 18)
2115+/** Selects no oversampling for 1080p */
2116+# define TV_OVERSAMPLE_NONE (2 << 18)
2117+/** Selects 8x oversampling */
2118+# define TV_OVERSAMPLE_8X (3 << 18)
2119+/** Selects progressive mode rather than interlaced */
2120+# define TV_PROGRESSIVE (1 << 17)
2121+/** Sets the colorburst to PAL mode. Required for non-M PAL modes. */
2122+# define TV_PAL_BURST (1 << 16)
2123+/** Field for setting delay of Y compared to C */
2124+# define TV_YC_SKEW_MASK (7 << 12)
2125+/** Enables a fix for 480p/576p standard definition modes on the 915GM only */
2126+# define TV_ENC_SDP_FIX (1 << 11)
2127+/**
2128+ * Enables a fix for the 915GM only.
2129+ *
2130+ * Not sure what it does.
2131+ */
2132+# define TV_ENC_C0_FIX (1 << 10)
2133+/** Bits that must be preserved by software */
2134+# define TV_CTL_SAVE ((3 << 8) | (3 << 6))
2135+# define TV_FUSE_STATE_MASK (3 << 4)
2136+/** Read-only state that reports all features enabled */
2137+# define TV_FUSE_STATE_ENABLED (0 << 4)
2138+/** Read-only state that reports that Macrovision is disabled in hardware*/
2139+# define TV_FUSE_STATE_NO_MACROVISION (1 << 4)
2140+/** Read-only state that reports that TV-out is disabled in hardware. */
2141+# define TV_FUSE_STATE_DISABLED (2 << 4)
2142+/** Normal operation */
2143+# define TV_TEST_MODE_NORMAL (0 << 0)
2144+/** Encoder test pattern 1 - combo pattern */
2145+# define TV_TEST_MODE_PATTERN_1 (1 << 0)
2146+/** Encoder test pattern 2 - full screen vertical 75% color bars */
2147+# define TV_TEST_MODE_PATTERN_2 (2 << 0)
2148+/** Encoder test pattern 3 - full screen horizontal 75% color bars */
2149+# define TV_TEST_MODE_PATTERN_3 (3 << 0)
2150+/** Encoder test pattern 4 - random noise */
2151+# define TV_TEST_MODE_PATTERN_4 (4 << 0)
2152+/** Encoder test pattern 5 - linear color ramps */
2153+# define TV_TEST_MODE_PATTERN_5 (5 << 0)
2154+/**
2155+ * This test mode forces the DACs to 50% of full output.
2156+ *
2157+ * This is used for load detection in combination with TVDAC_SENSE_MASK
2158+ */
2159+# define TV_TEST_MODE_MONITOR_DETECT (7 << 0)
2160+# define TV_TEST_MODE_MASK (7 << 0)
2161+
2162+#define TV_DAC 0x68004
2163+/**
2164+ * Reports that DAC state change logic has reported change (RO).
2165+ *
2166+ * This gets cleared when TV_DAC_STATE_EN is cleared
2167+*/
2168+# define TVDAC_STATE_CHG (1 << 31)
2169+# define TVDAC_SENSE_MASK (7 << 28)
2170+/** Reports that DAC A voltage is above the detect threshold */
2171+# define TVDAC_A_SENSE (1 << 30)
2172+/** Reports that DAC B voltage is above the detect threshold */
2173+# define TVDAC_B_SENSE (1 << 29)
2174+/** Reports that DAC C voltage is above the detect threshold */
2175+# define TVDAC_C_SENSE (1 << 28)
2176+/**
2177+ * Enables DAC state detection logic, for load-based TV detection.
2178+ *
2179+ * The PLL of the chosen pipe (in TV_CTL) must be running, and the encoder set
2180+ * to off, for load detection to work.
2181+ */
2182+# define TVDAC_STATE_CHG_EN (1 << 27)
2183+/** Sets the DAC A sense value to high */
2184+# define TVDAC_A_SENSE_CTL (1 << 26)
2185+/** Sets the DAC B sense value to high */
2186+# define TVDAC_B_SENSE_CTL (1 << 25)
2187+/** Sets the DAC C sense value to high */
2188+# define TVDAC_C_SENSE_CTL (1 << 24)
2189+/** Overrides the ENC_ENABLE and DAC voltage levels */
2190+# define DAC_CTL_OVERRIDE (1 << 7)
2191+/** Sets the slew rate. Must be preserved in software */
2192+# define ENC_TVDAC_SLEW_FAST (1 << 6)
2193+# define DAC_A_1_3_V (0 << 4)
2194+# define DAC_A_1_1_V (1 << 4)
2195+# define DAC_A_0_7_V (2 << 4)
2196+# define DAC_A_OFF (3 << 4)
2197+# define DAC_B_1_3_V (0 << 2)
2198+# define DAC_B_1_1_V (1 << 2)
2199+# define DAC_B_0_7_V (2 << 2)
2200+# define DAC_B_OFF (3 << 2)
2201+# define DAC_C_1_3_V (0 << 0)
2202+# define DAC_C_1_1_V (1 << 0)
2203+# define DAC_C_0_7_V (2 << 0)
2204+# define DAC_C_OFF (3 << 0)
2205+
2206+/**
2207+ * CSC coefficients are stored in a floating point format with 9 bits of
2208+ * mantissa and 2 or 3 bits of exponent. The exponent is represented as 2**-n,
2209+ * where 2-bit exponents are unsigned n, and 3-bit exponents are signed n with
2210+ * -1 (0x3) being the only legal negative value.
2211+ */
2212+#define TV_CSC_Y 0x68010
2213+# define TV_RY_MASK 0x07ff0000
2214+# define TV_RY_SHIFT 16
2215+# define TV_GY_MASK 0x00000fff
2216+# define TV_GY_SHIFT 0
2217+
2218+#define TV_CSC_Y2 0x68014
2219+# define TV_BY_MASK 0x07ff0000
2220+# define TV_BY_SHIFT 16
2221+/**
2222+ * Y attenuation for component video.
2223+ *
2224+ * Stored in 1.9 fixed point.
2225+ */
2226+# define TV_AY_MASK 0x000003ff
2227+# define TV_AY_SHIFT 0
2228+
2229+#define TV_CSC_U 0x68018
2230+# define TV_RU_MASK 0x07ff0000
2231+# define TV_RU_SHIFT 16
2232+# define TV_GU_MASK 0x000007ff
2233+# define TV_GU_SHIFT 0
2234+
2235+#define TV_CSC_U2 0x6801c
2236+# define TV_BU_MASK 0x07ff0000
2237+# define TV_BU_SHIFT 16
2238+/**
2239+ * U attenuation for component video.
2240+ *
2241+ * Stored in 1.9 fixed point.
2242+ */
2243+# define TV_AU_MASK 0x000003ff
2244+# define TV_AU_SHIFT 0
2245+
2246+#define TV_CSC_V 0x68020
2247+# define TV_RV_MASK 0x0fff0000
2248+# define TV_RV_SHIFT 16
2249+# define TV_GV_MASK 0x000007ff
2250+# define TV_GV_SHIFT 0
2251+
2252+#define TV_CSC_V2 0x68024
2253+# define TV_BV_MASK 0x07ff0000
2254+# define TV_BV_SHIFT 16
2255+/**
2256+ * V attenuation for component video.
2257+ *
2258+ * Stored in 1.9 fixed point.
2259+ */
2260+# define TV_AV_MASK 0x000007ff
2261+# define TV_AV_SHIFT 0
2262+
2263+#define TV_CLR_KNOBS 0x68028
2264+/** 2s-complement brightness adjustment */
2265+# define TV_BRIGHTNESS_MASK 0xff000000
2266+# define TV_BRIGHTNESS_SHIFT 24
2267+/** Contrast adjustment, as a 2.6 unsigned floating point number */
2268+# define TV_CONTRAST_MASK 0x00ff0000
2269+# define TV_CONTRAST_SHIFT 16
2270+/** Saturation adjustment, as a 2.6 unsigned floating point number */
2271+# define TV_SATURATION_MASK 0x0000ff00
2272+# define TV_SATURATION_SHIFT 8
2273+/** Hue adjustment, as an integer phase angle in degrees */
2274+# define TV_HUE_MASK 0x000000ff
2275+# define TV_HUE_SHIFT 0
2276+
2277+#define TV_CLR_LEVEL 0x6802c
2278+/** Controls the DAC level for black */
2279+# define TV_BLACK_LEVEL_MASK 0x01ff0000
2280+# define TV_BLACK_LEVEL_SHIFT 16
2281+/** Controls the DAC level for blanking */
2282+# define TV_BLANK_LEVEL_MASK 0x000001ff
2283+# define TV_BLANK_LEVEL_SHIFT 0
2284+
2285+#define TV_H_CTL_1 0x68030
2286+/** Number of pixels in the hsync. */
2287+# define TV_HSYNC_END_MASK 0x1fff0000
2288+# define TV_HSYNC_END_SHIFT 16
2289+/** Total number of pixels minus one in the line (display and blanking). */
2290+# define TV_HTOTAL_MASK 0x00001fff
2291+# define TV_HTOTAL_SHIFT 0
2292+
2293+#define TV_H_CTL_2 0x68034
2294+/** Enables the colorburst (needed for non-component color) */
2295+# define TV_BURST_ENA (1 << 31)
2296+/** Offset of the colorburst from the start of hsync, in pixels minus one. */
2297+# define TV_HBURST_START_SHIFT 16
2298+# define TV_HBURST_START_MASK 0x1fff0000
2299+/** Length of the colorburst */
2300+# define TV_HBURST_LEN_SHIFT 0
2301+# define TV_HBURST_LEN_MASK 0x0001fff
2302+
2303+#define TV_H_CTL_3 0x68038
2304+/** End of hblank, measured in pixels minus one from start of hsync */
2305+# define TV_HBLANK_END_SHIFT 16
2306+# define TV_HBLANK_END_MASK 0x1fff0000
2307+/** Start of hblank, measured in pixels minus one from start of hsync */
2308+# define TV_HBLANK_START_SHIFT 0
2309+# define TV_HBLANK_START_MASK 0x0001fff
2310+
2311+#define TV_V_CTL_1 0x6803c
2312+/** XXX */
2313+# define TV_NBR_END_SHIFT 16
2314+# define TV_NBR_END_MASK 0x07ff0000
2315+/** XXX */
2316+# define TV_VI_END_F1_SHIFT 8
2317+# define TV_VI_END_F1_MASK 0x00003f00
2318+/** XXX */
2319+# define TV_VI_END_F2_SHIFT 0
2320+# define TV_VI_END_F2_MASK 0x0000003f
2321+
2322+#define TV_V_CTL_2 0x68040
2323+/** Length of vsync, in half lines */
2324+# define TV_VSYNC_LEN_MASK 0x07ff0000
2325+# define TV_VSYNC_LEN_SHIFT 16
2326+/** Offset of the start of vsync in field 1, measured in one less than the
2327+ * number of half lines.
2328+ */
2329+# define TV_VSYNC_START_F1_MASK 0x00007f00
2330+# define TV_VSYNC_START_F1_SHIFT 8
2331+/**
2332+ * Offset of the start of vsync in field 2, measured in one less than the
2333+ * number of half lines.
2334+ */
2335+# define TV_VSYNC_START_F2_MASK 0x0000007f
2336+# define TV_VSYNC_START_F2_SHIFT 0
2337+
2338+#define TV_V_CTL_3 0x68044
2339+/** Enables generation of the equalization signal */
2340+# define TV_EQUAL_ENA (1 << 31)
2341+/** Length of vsync, in half lines */
2342+# define TV_VEQ_LEN_MASK 0x007f0000
2343+# define TV_VEQ_LEN_SHIFT 16
2344+/** Offset of the start of equalization in field 1, measured in one less than
2345+ * the number of half lines.
2346+ */
2347+# define TV_VEQ_START_F1_MASK 0x0007f00
2348+# define TV_VEQ_START_F1_SHIFT 8
2349+/**
2350+ * Offset of the start of equalization in field 2, measured in one less than
2351+ * the number of half lines.
2352+ */
2353+# define TV_VEQ_START_F2_MASK 0x000007f
2354+# define TV_VEQ_START_F2_SHIFT 0
2355+
2356+#define TV_V_CTL_4 0x68048
2357+/**
2358+ * Offset to start of vertical colorburst, measured in one less than the
2359+ * number of lines from vertical start.
2360+ */
2361+# define TV_VBURST_START_F1_MASK 0x003f0000
2362+# define TV_VBURST_START_F1_SHIFT 16
2363+/**
2364+ * Offset to the end of vertical colorburst, measured in one less than the
2365+ * number of lines from the start of NBR.
2366+ */
2367+# define TV_VBURST_END_F1_MASK 0x000000ff
2368+# define TV_VBURST_END_F1_SHIFT 0
2369+
2370+#define TV_V_CTL_5 0x6804c
2371+/**
2372+ * Offset to start of vertical colorburst, measured in one less than the
2373+ * number of lines from vertical start.
2374+ */
2375+# define TV_VBURST_START_F2_MASK 0x003f0000
2376+# define TV_VBURST_START_F2_SHIFT 16
2377+/**
2378+ * Offset to the end of vertical colorburst, measured in one less than the
2379+ * number of lines from the start of NBR.
2380+ */
2381+# define TV_VBURST_END_F2_MASK 0x000000ff
2382+# define TV_VBURST_END_F2_SHIFT 0
2383+
2384+#define TV_V_CTL_6 0x68050
2385+/**
2386+ * Offset to start of vertical colorburst, measured in one less than the
2387+ * number of lines from vertical start.
2388+ */
2389+# define TV_VBURST_START_F3_MASK 0x003f0000
2390+# define TV_VBURST_START_F3_SHIFT 16
2391+/**
2392+ * Offset to the end of vertical colorburst, measured in one less than the
2393+ * number of lines from the start of NBR.
2394+ */
2395+# define TV_VBURST_END_F3_MASK 0x000000ff
2396+# define TV_VBURST_END_F3_SHIFT 0
2397+
2398+#define TV_V_CTL_7 0x68054
2399+/**
2400+ * Offset to start of vertical colorburst, measured in one less than the
2401+ * number of lines from vertical start.
2402+ */
2403+# define TV_VBURST_START_F4_MASK 0x003f0000
2404+# define TV_VBURST_START_F4_SHIFT 16
2405+/**
2406+ * Offset to the end of vertical colorburst, measured in one less than the
2407+ * number of lines from the start of NBR.
2408+ */
2409+# define TV_VBURST_END_F4_MASK 0x000000ff
2410+# define TV_VBURST_END_F4_SHIFT 0
2411+
2412+#define TV_SC_CTL_1 0x68060
2413+/** Turns on the first subcarrier phase generation DDA */
2414+# define TV_SC_DDA1_EN (1 << 31)
2415+/** Turns on the first subcarrier phase generation DDA */
2416+# define TV_SC_DDA2_EN (1 << 30)
2417+/** Turns on the first subcarrier phase generation DDA */
2418+# define TV_SC_DDA3_EN (1 << 29)
2419+/** Sets the subcarrier DDA to reset frequency every other field */
2420+# define TV_SC_RESET_EVERY_2 (0 << 24)
2421+/** Sets the subcarrier DDA to reset frequency every fourth field */
2422+# define TV_SC_RESET_EVERY_4 (1 << 24)
2423+/** Sets the subcarrier DDA to reset frequency every eighth field */
2424+# define TV_SC_RESET_EVERY_8 (2 << 24)
2425+/** Sets the subcarrier DDA to never reset the frequency */
2426+# define TV_SC_RESET_NEVER (3 << 24)
2427+/** Sets the peak amplitude of the colorburst.*/
2428+# define TV_BURST_LEVEL_MASK 0x00ff0000
2429+# define TV_BURST_LEVEL_SHIFT 16
2430+/** Sets the increment of the first subcarrier phase generation DDA */
2431+# define TV_SCDDA1_INC_MASK 0x00000fff
2432+# define TV_SCDDA1_INC_SHIFT 0
2433+
2434+#define TV_SC_CTL_2 0x68064
2435+/** Sets the rollover for the second subcarrier phase generation DDA */
2436+# define TV_SCDDA2_SIZE_MASK 0x7fff0000
2437+# define TV_SCDDA2_SIZE_SHIFT 16
2438+/** Sets the increent of the second subcarrier phase generation DDA */
2439+# define TV_SCDDA2_INC_MASK 0x00007fff
2440+# define TV_SCDDA2_INC_SHIFT 0
2441+
2442+#define TV_SC_CTL_3 0x68068
2443+/** Sets the rollover for the third subcarrier phase generation DDA */
2444+# define TV_SCDDA3_SIZE_MASK 0x7fff0000
2445+# define TV_SCDDA3_SIZE_SHIFT 16
2446+/** Sets the increent of the third subcarrier phase generation DDA */
2447+# define TV_SCDDA3_INC_MASK 0x00007fff
2448+# define TV_SCDDA3_INC_SHIFT 0
2449+
2450+#define TV_WIN_POS 0x68070
2451+/** X coordinate of the display from the start of horizontal active */
2452+# define TV_XPOS_MASK 0x1fff0000
2453+# define TV_XPOS_SHIFT 16
2454+/** Y coordinate of the display from the start of vertical active (NBR) */
2455+# define TV_YPOS_MASK 0x00000fff
2456+# define TV_YPOS_SHIFT 0
2457+
2458+#define TV_WIN_SIZE 0x68074
2459+/** Horizontal size of the display window, measured in pixels*/
2460+# define TV_XSIZE_MASK 0x1fff0000
2461+# define TV_XSIZE_SHIFT 16
2462+/**
2463+ * Vertical size of the display window, measured in pixels.
2464+ *
2465+ * Must be even for interlaced modes.
2466+ */
2467+# define TV_YSIZE_MASK 0x00000fff
2468+# define TV_YSIZE_SHIFT 0
2469+
2470+#define TV_FILTER_CTL_1 0x68080
2471+/**
2472+ * Enables automatic scaling calculation.
2473+ *
2474+ * If set, the rest of the registers are ignored, and the calculated values can
2475+ * be read back from the register.
2476+ */
2477+# define TV_AUTO_SCALE (1 << 31)
2478+/**
2479+ * Disables the vertical filter.
2480+ *
2481+ * This is required on modes more than 1024 pixels wide */
2482+# define TV_V_FILTER_BYPASS (1 << 29)
2483+/** Enables adaptive vertical filtering */
2484+# define TV_VADAPT (1 << 28)
2485+# define TV_VADAPT_MODE_MASK (3 << 26)
2486+/** Selects the least adaptive vertical filtering mode */
2487+# define TV_VADAPT_MODE_LEAST (0 << 26)
2488+/** Selects the moderately adaptive vertical filtering mode */
2489+# define TV_VADAPT_MODE_MODERATE (1 << 26)
2490+/** Selects the most adaptive vertical filtering mode */
2491+# define TV_VADAPT_MODE_MOST (3 << 26)
2492+/**
2493+ * Sets the horizontal scaling factor.
2494+ *
2495+ * This should be the fractional part of the horizontal scaling factor divided
2496+ * by the oversampling rate. TV_HSCALE should be less than 1, and set to:
2497+ *
2498+ * (src width - 1) / ((oversample * dest width) - 1)
2499+ */
2500+# define TV_HSCALE_FRAC_MASK 0x00003fff
2501+# define TV_HSCALE_FRAC_SHIFT 0
2502+
2503+#define TV_FILTER_CTL_2 0x68084
2504+/**
2505+ * Sets the integer part of the 3.15 fixed-point vertical scaling factor.
2506+ *
2507+ * TV_VSCALE should be (src height - 1) / ((interlace * dest height) - 1)
2508+ */
2509+# define TV_VSCALE_INT_MASK 0x00038000
2510+# define TV_VSCALE_INT_SHIFT 15
2511+/**
2512+ * Sets the fractional part of the 3.15 fixed-point vertical scaling factor.
2513+ *
2514+ * \sa TV_VSCALE_INT_MASK
2515+ */
2516+# define TV_VSCALE_FRAC_MASK 0x00007fff
2517+# define TV_VSCALE_FRAC_SHIFT 0
2518+
2519+#define TV_FILTER_CTL_3 0x68088
2520+/**
2521+ * Sets the integer part of the 3.15 fixed-point vertical scaling factor.
2522+ *
2523+ * TV_VSCALE should be (src height - 1) / (1/4 * (dest height - 1))
2524+ *
2525+ * For progressive modes, TV_VSCALE_IP_INT should be set to zeroes.
2526+ */
2527+# define TV_VSCALE_IP_INT_MASK 0x00038000
2528+# define TV_VSCALE_IP_INT_SHIFT 15
2529+/**
2530+ * Sets the fractional part of the 3.15 fixed-point vertical scaling factor.
2531+ *
2532+ * For progressive modes, TV_VSCALE_IP_INT should be set to zeroes.
2533+ *
2534+ * \sa TV_VSCALE_IP_INT_MASK
2535+ */
2536+# define TV_VSCALE_IP_FRAC_MASK 0x00007fff
2537+# define TV_VSCALE_IP_FRAC_SHIFT 0
2538+
2539+#define TV_CC_CONTROL 0x68090
2540+# define TV_CC_ENABLE (1 << 31)
2541+/**
2542+ * Specifies which field to send the CC data in.
2543+ *
2544+ * CC data is usually sent in field 0.
2545+ */
2546+# define TV_CC_FID_MASK (1 << 27)
2547+# define TV_CC_FID_SHIFT 27
2548+/** Sets the horizontal position of the CC data. Usually 135. */
2549+# define TV_CC_HOFF_MASK 0x03ff0000
2550+# define TV_CC_HOFF_SHIFT 16
2551+/** Sets the vertical position of the CC data. Usually 21 */
2552+# define TV_CC_LINE_MASK 0x0000003f
2553+# define TV_CC_LINE_SHIFT 0
2554+
2555+#define TV_CC_DATA 0x68094
2556+# define TV_CC_RDY (1 << 31)
2557+/** Second word of CC data to be transmitted. */
2558+# define TV_CC_DATA_2_MASK 0x007f0000
2559+# define TV_CC_DATA_2_SHIFT 16
2560+/** First word of CC data to be transmitted. */
2561+# define TV_CC_DATA_1_MASK 0x0000007f
2562+# define TV_CC_DATA_1_SHIFT 0
2563+
2564+#define TV_H_LUMA_0 0x68100
2565+#define TV_H_LUMA_59 0x681ec
2566+#define TV_H_CHROMA_0 0x68200
2567+#define TV_H_CHROMA_59 0x682ec
2568+#define TV_V_LUMA_0 0x68300
2569+#define TV_V_LUMA_42 0x683a8
2570+#define TV_V_CHROMA_0 0x68400
2571+#define TV_V_CHROMA_42 0x684a8
2572+
2573+/* Display & cursor control */
2574+
2575+/* Pipe A */
2576+#define PIPEADSL 0x70000
2577+#define PIPEACONF 0x70008
2578+#define PIPEACONF_ENABLE (1<<31)
2579+#define PIPEACONF_DISABLE 0
2580+#define PIPEACONF_DOUBLE_WIDE (1<<30)
2581+#define I965_PIPECONF_ACTIVE (1<<30)
2582+#define PIPEACONF_SINGLE_WIDE 0
2583+#define PIPEACONF_PIPE_UNLOCKED 0
2584+#define PIPEACONF_PIPE_LOCKED (1<<25)
2585+#define PIPEACONF_PALETTE 0
2586+#define PIPEACONF_GAMMA (1<<24)
2587+#define PIPECONF_FORCE_BORDER (1<<25)
2588+#define PIPECONF_PROGRESSIVE (0 << 21)
2589+#define PIPECONF_INTERLACE_W_FIELD_INDICATION (6 << 21)
2590+#define PIPECONF_INTERLACE_FIELD_0_ONLY (7 << 21)
2591+#define PIPEASTAT 0x70024
2592+#define PIPE_FIFO_UNDERRUN_STATUS (1UL<<31)
2593+#define PIPE_CRC_ERROR_ENABLE (1UL<<29)
2594+#define PIPE_CRC_DONE_ENABLE (1UL<<28)
2595+#define PIPE_GMBUS_EVENT_ENABLE (1UL<<27)
2596+#define PIPE_HOTPLUG_INTERRUPT_ENABLE (1UL<<26)
2597+#define PIPE_VSYNC_INTERRUPT_ENABLE (1UL<<25)
2598+#define PIPE_DISPLAY_LINE_COMPARE_ENABLE (1UL<<24)
2599+#define PIPE_DPST_EVENT_ENABLE (1UL<<23)
2600+#define PIPE_LEGACY_BLC_EVENT_ENABLE (1UL<<22)
2601+#define PIPE_ODD_FIELD_INTERRUPT_ENABLE (1UL<<21)
2602+#define PIPE_EVEN_FIELD_INTERRUPT_ENABLE (1UL<<20)
2603+#define PIPE_HOTPLUG_TV_INTERRUPT_ENABLE (1UL<<18) /* pre-965 */
2604+#define PIPE_START_VBLANK_INTERRUPT_ENABLE (1UL<<18) /* 965 or later */
2605+#define PIPE_VBLANK_INTERRUPT_ENABLE (1UL<<17)
2606+#define PIPE_OVERLAY_UPDATED_ENABLE (1UL<<16)
2607+#define PIPE_CRC_ERROR_INTERRUPT_STATUS (1UL<<13)
2608+#define PIPE_CRC_DONE_INTERRUPT_STATUS (1UL<<12)
2609+#define PIPE_GMBUS_INTERRUPT_STATUS (1UL<<11)
2610+#define PIPE_HOTPLUG_INTERRUPT_STATUS (1UL<<10)
2611+#define PIPE_VSYNC_INTERRUPT_STATUS (1UL<<9)
2612+#define PIPE_DISPLAY_LINE_COMPARE_STATUS (1UL<<8)
2613+#define PIPE_DPST_EVENT_STATUS (1UL<<7)
2614+#define PIPE_LEGACY_BLC_EVENT_STATUS (1UL<<6)
2615+#define PIPE_ODD_FIELD_INTERRUPT_STATUS (1UL<<5)
2616+#define PIPE_EVEN_FIELD_INTERRUPT_STATUS (1UL<<4)
2617+#define PIPE_HOTPLUG_TV_INTERRUPT_STATUS (1UL<<2) /* pre-965 */
2618+#define PIPE_START_VBLANK_INTERRUPT_STATUS (1UL<<2) /* 965 or later */
2619+#define PIPE_VBLANK_INTERRUPT_STATUS (1UL<<1)
2620+#define PIPE_OVERLAY_UPDATED_STATUS (1UL<<0)
2621+
2622+#define DSPARB 0x70030
2623+#define DSPARB_CSTART_MASK (0x7f << 7)
2624+#define DSPARB_CSTART_SHIFT 7
2625+#define DSPARB_BSTART_MASK (0x7f)
2626+#define DSPARB_BSTART_SHIFT 0
2627+/*
2628+ * The two pipe frame counter registers are not synchronized, so
2629+ * reading a stable value is somewhat tricky. The following code
2630+ * should work:
2631+ *
2632+ * do {
2633+ * high1 = ((INREG(PIPEAFRAMEHIGH) & PIPE_FRAME_HIGH_MASK) >>
2634+ * PIPE_FRAME_HIGH_SHIFT;
2635+ * low1 = ((INREG(PIPEAFRAMEPIXEL) & PIPE_FRAME_LOW_MASK) >>
2636+ * PIPE_FRAME_LOW_SHIFT);
2637+ * high2 = ((INREG(PIPEAFRAMEHIGH) & PIPE_FRAME_HIGH_MASK) >>
2638+ * PIPE_FRAME_HIGH_SHIFT);
2639+ * } while (high1 != high2);
2640+ * frame = (high1 << 8) | low1;
2641+ */
2642+#define PIPEAFRAMEHIGH 0x70040
2643+#define PIPE_FRAME_HIGH_MASK 0x0000ffff
2644+#define PIPE_FRAME_HIGH_SHIFT 0
2645+#define PIPEAFRAMEPIXEL 0x70044
2646+#define PIPE_FRAME_LOW_MASK 0xff000000
2647+#define PIPE_FRAME_LOW_SHIFT 24
2648+#define PIPE_PIXEL_MASK 0x00ffffff
2649+#define PIPE_PIXEL_SHIFT 0
2650+
2651+/* Cursor A & B regs */
2652+#define CURACNTR 0x70080
2653+#define CURSOR_MODE_DISABLE 0x00
2654+#define CURSOR_MODE_64_32B_AX 0x07
2655+#define CURSOR_MODE_64_ARGB_AX ((1 << 5) | CURSOR_MODE_64_32B_AX)
2656+#define MCURSOR_GAMMA_ENABLE (1 << 26)
2657+#define CURABASE 0x70084
2658+#define CURAPOS 0x70088
2659+#define CURSOR_POS_MASK 0x007FF
2660+#define CURSOR_POS_SIGN 0x8000
2661+#define CURSOR_X_SHIFT 0
2662+#define CURSOR_Y_SHIFT 16
2663+#define CURBCNTR 0x700c0
2664+#define CURBBASE 0x700c4
2665+#define CURBPOS 0x700c8
2666+
2667+/* Display A control */
2668+#define DSPACNTR 0x70180
2669+#define DISPLAY_PLANE_ENABLE (1<<31)
2670+#define DISPLAY_PLANE_DISABLE 0
2671+#define DISPPLANE_GAMMA_ENABLE (1<<30)
2672+#define DISPPLANE_GAMMA_DISABLE 0
2673+#define DISPPLANE_PIXFORMAT_MASK (0xf<<26)
2674+#define DISPPLANE_8BPP (0x2<<26)
2675+#define DISPPLANE_15_16BPP (0x4<<26)
2676+#define DISPPLANE_16BPP (0x5<<26)
2677+#define DISPPLANE_32BPP_NO_ALPHA (0x6<<26)
2678+#define DISPPLANE_32BPP (0x7<<26)
2679+#define DISPPLANE_STEREO_ENABLE (1<<25)
2680+#define DISPPLANE_STEREO_DISABLE 0
2681+#define DISPPLANE_SEL_PIPE_MASK (1<<24)
2682+#define DISPPLANE_SEL_PIPE_A 0
2683+#define DISPPLANE_SEL_PIPE_B (1<<24)
2684+#define DISPPLANE_SRC_KEY_ENABLE (1<<22)
2685+#define DISPPLANE_SRC_KEY_DISABLE 0
2686+#define DISPPLANE_LINE_DOUBLE (1<<20)
2687+#define DISPPLANE_NO_LINE_DOUBLE 0
2688+#define DISPPLANE_STEREO_POLARITY_FIRST 0
2689+#define DISPPLANE_STEREO_POLARITY_SECOND (1<<18)
2690+#define DSPAADDR 0x70184
2691+#define DSPASTRIDE 0x70188
2692+#define DSPAPOS 0x7018C /* reserved */
2693+#define DSPASIZE 0x70190
2694+#define DSPASURF 0x7019C /* 965+ only */
2695+#define DSPATILEOFF 0x701A4 /* 965+ only */
2696+
2697+/* VBIOS flags */
2698+#define SWF00 0x71410
2699+#define SWF01 0x71414
2700+#define SWF02 0x71418
2701+#define SWF03 0x7141c
2702+#define SWF04 0x71420
2703+#define SWF05 0x71424
2704+#define SWF06 0x71428
2705+#define SWF10 0x70410
2706+#define SWF11 0x70414
2707+#define SWF14 0x71420
2708+#define SWF30 0x72414
2709+#define SWF31 0x72418
2710+#define SWF32 0x7241c
2711+
2712+/* Pipe B */
2713+#define PIPEBDSL 0x71000
2714+#define PIPEBCONF 0x71008
2715+#define PIPEBSTAT 0x71024
2716+#define PIPEBFRAMEHIGH 0x71040
2717+#define PIPEBFRAMEPIXEL 0x71044
2718+
2719+/* Display B control */
2720+#define DSPBCNTR 0x71180
2721+#define DISPPLANE_ALPHA_TRANS_ENABLE (1<<15)
2722+#define DISPPLANE_ALPHA_TRANS_DISABLE 0
2723+#define DISPPLANE_SPRITE_ABOVE_DISPLAY 0
2724+#define DISPPLANE_SPRITE_ABOVE_OVERLAY (1)
2725+#define DSPBADDR 0x71184
2726+#define DSPBSTRIDE 0x71188
2727+#define DSPBPOS 0x7118C
2728+#define DSPBSIZE 0x71190
2729+#define DSPBSURF 0x7119C
2730+#define DSPBTILEOFF 0x711A4
2731+
2732+/* VBIOS regs */
2733+#define VGACNTRL 0x71400
2734+# define VGA_DISP_DISABLE (1 << 31)
2735+# define VGA_2X_MODE (1 << 30)
2736+# define VGA_PIPE_B_SELECT (1 << 29)
2737+
2738+#endif /* _I915_REG_H_ */
2739
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27-rc1/0003_i915.Add_support_for_MSI_and_interrupt_mitigation.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc1/0003_i915.Add_support_for_MSI_and_interrupt_mitigation.patch
new file mode 100644
index 0000000000..70f91194e4
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc1/0003_i915.Add_support_for_MSI_and_interrupt_mitigation.patch
@@ -0,0 +1,421 @@
1From: Eric Anholt <eric@anholt.net>
2Date: Tue, 29 Jul 2008 19:10:39 +0000 (-0700)
3Subject: i915: Add support for MSI and interrupt mitigation.
4X-Git-Tag: v2.6.12-rc2
5X-Git-Url: http://gitweb.freedesktop.org/?p=users/anholt/anholt/linux-2.6.git;a=commitdiff;h=aae4223e2fd3b29ae8e070b7a16d8cfc70c6a0c0
6
7i915: Add support for MSI and interrupt mitigation.
8
9Previous attempts at interrupt mitigation had been foiled by i915_wait_irq's
10failure to update the sarea seqno value when the status page indicated that
11the seqno had already been passed. MSI support has been seen to cut CPU
12costs by up to 40% in some workloads by avoiding other expensive interrupt
13handlers for frequent graphics interrupts.
14
15Signed-off-by: Eric Anholt <eric@anholt.net>
16---
17
18--- a/drivers/gpu/drm/drm_irq.c
19+++ b/drivers/gpu/drm/drm_irq.c
20@@ -63,7 +63,7 @@ int drm_irq_by_busid(struct drm_device *
21 p->devnum != PCI_SLOT(dev->pdev->devfn) || p->funcnum != PCI_FUNC(dev->pdev->devfn))
22 return -EINVAL;
23
24- p->irq = dev->irq;
25+ p->irq = dev->pdev->irq;
26
27 DRM_DEBUG("%d:%d:%d => IRQ %d\n", p->busnum, p->devnum, p->funcnum,
28 p->irq);
29@@ -89,7 +89,7 @@ static int drm_irq_install(struct drm_de
30 if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
31 return -EINVAL;
32
33- if (dev->irq == 0)
34+ if (dev->pdev->irq == 0)
35 return -EINVAL;
36
37 mutex_lock(&dev->struct_mutex);
38@@ -107,7 +107,7 @@ static int drm_irq_install(struct drm_de
39 dev->irq_enabled = 1;
40 mutex_unlock(&dev->struct_mutex);
41
42- DRM_DEBUG("irq=%d\n", dev->irq);
43+ DRM_DEBUG("irq=%d\n", dev->pdev->irq);
44
45 if (drm_core_check_feature(dev, DRIVER_IRQ_VBL)) {
46 init_waitqueue_head(&dev->vbl_queue);
47@@ -127,8 +127,12 @@ static int drm_irq_install(struct drm_de
48 if (drm_core_check_feature(dev, DRIVER_IRQ_SHARED))
49 sh_flags = IRQF_SHARED;
50
51- ret = request_irq(dev->irq, dev->driver->irq_handler,
52+ ret = request_irq(dev->pdev->irq, dev->driver->irq_handler,
53 sh_flags, dev->devname, dev);
54+ /* Expose the device irq number to drivers that want to export it for
55+ * whatever reason.
56+ */
57+ dev->irq = dev->pdev->irq;
58 if (ret < 0) {
59 mutex_lock(&dev->struct_mutex);
60 dev->irq_enabled = 0;
61@@ -164,11 +168,11 @@ int drm_irq_uninstall(struct drm_device
62 if (!irq_enabled)
63 return -EINVAL;
64
65- DRM_DEBUG("irq=%d\n", dev->irq);
66+ DRM_DEBUG("irq=%d\n", dev->pdev->irq);
67
68 dev->driver->irq_uninstall(dev);
69
70- free_irq(dev->irq, dev);
71+ free_irq(dev->pdev->irq, dev);
72
73 dev->locked_tasklet_func = NULL;
74
75@@ -201,7 +205,7 @@ int drm_control(struct drm_device *dev,
76 if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
77 return 0;
78 if (dev->if_version < DRM_IF_VERSION(1, 2) &&
79- ctl->irq != dev->irq)
80+ ctl->irq != dev->pdev->irq)
81 return -EINVAL;
82 return drm_irq_install(dev);
83 case DRM_UNINST_HANDLER:
84@@ -239,7 +243,7 @@ int drm_wait_vblank(struct drm_device *d
85 int ret = 0;
86 unsigned int flags, seq;
87
88- if ((!dev->irq) || (!dev->irq_enabled))
89+ if ((!dev->pdev->irq) || (!dev->irq_enabled))
90 return -EINVAL;
91
92 if (vblwait->request.type &
93--- a/drivers/gpu/drm/i915/i915_dma.c
94+++ b/drivers/gpu/drm/i915/i915_dma.c
95@@ -84,7 +84,7 @@ static int i915_dma_cleanup(struct drm_d
96 * may not have been called from userspace and after dev_private
97 * is freed, it's too late.
98 */
99- if (dev->irq)
100+ if (dev->irq_enabled)
101 drm_irq_uninstall(dev);
102
103 if (dev_priv->ring.virtual_start) {
104@@ -644,7 +644,7 @@ static int i915_getparam(struct drm_devi
105
106 switch (param->param) {
107 case I915_PARAM_IRQ_ACTIVE:
108- value = dev->irq ? 1 : 0;
109+ value = dev->irq_enabled;
110 break;
111 case I915_PARAM_ALLOW_BATCHBUFFER:
112 value = dev_priv->allow_batchbuffer ? 1 : 0;
113@@ -763,6 +763,20 @@ int i915_driver_load(struct drm_device *
114 ret = drm_addmap(dev, base, size, _DRM_REGISTERS,
115 _DRM_KERNEL | _DRM_DRIVER,
116 &dev_priv->mmio_map);
117+
118+
119+ /* On the 945G/GM, the chipset reports the MSI capability on the
120+ * integrated graphics even though the support isn't actually there
121+ * according to the published specs. It doesn't appear to function
122+ * correctly in testing on 945G.
123+ * This may be a side effect of MSI having been made available for PEG
124+ * and the registers being closely associated.
125+ */
126+ if (!IS_I945G(dev) && !IS_I945GM(dev))
127+ pci_enable_msi(dev->pdev);
128+
129+ spin_lock_init(&dev_priv->user_irq_lock);
130+
131 return ret;
132 }
133
134@@ -770,6 +784,9 @@ int i915_driver_unload(struct drm_device
135 {
136 struct drm_i915_private *dev_priv = dev->dev_private;
137
138+ if (dev->pdev->msi_enabled)
139+ pci_disable_msi(dev->pdev);
140+
141 if (dev_priv->mmio_map)
142 drm_rmmap(dev, dev_priv->mmio_map);
143
144--- a/drivers/gpu/drm/i915/i915_drv.h
145+++ b/drivers/gpu/drm/i915/i915_drv.h
146@@ -105,6 +105,12 @@ typedef struct drm_i915_private {
147 wait_queue_head_t irq_queue;
148 atomic_t irq_received;
149 atomic_t irq_emitted;
150+ /** Protects user_irq_refcount and irq_mask_reg */
151+ spinlock_t user_irq_lock;
152+ /** Refcount for i915_user_irq_get() versus i915_user_irq_put(). */
153+ int user_irq_refcount;
154+ /** Cached value of IMR to avoid reads in updating the bitfield */
155+ u32 irq_mask_reg;
156
157 int tex_lru_log_granularity;
158 int allow_batchbuffer;
159--- a/drivers/gpu/drm/i915/i915_irq.c
160+++ b/drivers/gpu/drm/i915/i915_irq.c
161@@ -33,6 +33,31 @@
162
163 #define MAX_NOPID ((u32)~0)
164
165+/** These are the interrupts used by the driver */
166+#define I915_INTERRUPT_ENABLE_MASK (I915_USER_INTERRUPT | \
167+ I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT | \
168+ I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT)
169+
170+static inline void
171+i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask)
172+{
173+ if ((dev_priv->irq_mask_reg & mask) != 0) {
174+ dev_priv->irq_mask_reg &= ~mask;
175+ I915_WRITE(IMR, dev_priv->irq_mask_reg);
176+ (void) I915_READ(IMR);
177+ }
178+}
179+
180+static inline void
181+i915_disable_irq(drm_i915_private_t *dev_priv, u32 mask)
182+{
183+ if ((dev_priv->irq_mask_reg & mask) != mask) {
184+ dev_priv->irq_mask_reg |= mask;
185+ I915_WRITE(IMR, dev_priv->irq_mask_reg);
186+ (void) I915_READ(IMR);
187+ }
188+}
189+
190 /**
191 * Emit blits for scheduled buffer swaps.
192 *
193@@ -229,46 +254,50 @@ irqreturn_t i915_driver_irq_handler(DRM_
194 {
195 struct drm_device *dev = (struct drm_device *) arg;
196 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
197- u16 temp;
198 u32 pipea_stats, pipeb_stats;
199+ u32 iir;
200
201 pipea_stats = I915_READ(PIPEASTAT);
202 pipeb_stats = I915_READ(PIPEBSTAT);
203
204- temp = I915_READ16(IIR);
205-
206- temp &= (I915_USER_INTERRUPT |
207- I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT |
208- I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT);
209-
210- DRM_DEBUG("%s flag=%08x\n", __FUNCTION__, temp);
211-
212- if (temp == 0)
213+ if (dev->pdev->msi_enabled)
214+ I915_WRITE(IMR, ~0);
215+ iir = I915_READ(IIR);
216+
217+ DRM_DEBUG("iir=%08x\n", iir);
218+
219+ if (iir == 0) {
220+ if (dev->pdev->msi_enabled) {
221+ I915_WRITE(IMR, dev_priv->irq_mask_reg);
222+ (void) I915_READ(IMR);
223+ }
224 return IRQ_NONE;
225+ }
226
227- I915_WRITE16(IIR, temp);
228- (void) I915_READ16(IIR);
229- DRM_READMEMORYBARRIER();
230+ I915_WRITE(IIR, iir);
231+ if (dev->pdev->msi_enabled)
232+ I915_WRITE(IMR, dev_priv->irq_mask_reg);
233+ (void) I915_READ(IIR); /* Flush posted writes */
234
235 dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
236
237- if (temp & I915_USER_INTERRUPT)
238+ if (iir & I915_USER_INTERRUPT)
239 DRM_WAKEUP(&dev_priv->irq_queue);
240
241- if (temp & (I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT |
242- I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT)) {
243+ if (iir & (I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT |
244+ I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT)) {
245 int vblank_pipe = dev_priv->vblank_pipe;
246
247 if ((vblank_pipe &
248 (DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B))
249 == (DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B)) {
250- if (temp & I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT)
251+ if (iir & I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT)
252 atomic_inc(&dev->vbl_received);
253- if (temp & I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT)
254+ if (iir & I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT)
255 atomic_inc(&dev->vbl_received2);
256- } else if (((temp & I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT) &&
257+ } else if (((iir & I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT) &&
258 (vblank_pipe & DRM_I915_VBLANK_PIPE_A)) ||
259- ((temp & I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT) &&
260+ ((iir & I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT) &&
261 (vblank_pipe & DRM_I915_VBLANK_PIPE_B)))
262 atomic_inc(&dev->vbl_received);
263
264@@ -314,6 +343,27 @@ static int i915_emit_irq(struct drm_devi
265 return dev_priv->counter;
266 }
267
268+static void i915_user_irq_get(struct drm_device *dev)
269+{
270+ drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
271+
272+ spin_lock(&dev_priv->user_irq_lock);
273+ if (dev->irq_enabled && (++dev_priv->user_irq_refcount == 1))
274+ i915_enable_irq(dev_priv, I915_USER_INTERRUPT);
275+ spin_unlock(&dev_priv->user_irq_lock);
276+}
277+
278+static void i915_user_irq_put(struct drm_device *dev)
279+{
280+ drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
281+
282+ spin_lock(&dev_priv->user_irq_lock);
283+ BUG_ON(dev->irq_enabled && dev_priv->user_irq_refcount <= 0);
284+ if (dev->irq_enabled && (--dev_priv->user_irq_refcount == 0))
285+ i915_disable_irq(dev_priv, I915_USER_INTERRUPT);
286+ spin_unlock(&dev_priv->user_irq_lock);
287+}
288+
289 static int i915_wait_irq(struct drm_device * dev, int irq_nr)
290 {
291 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
292@@ -322,13 +372,17 @@ static int i915_wait_irq(struct drm_devi
293 DRM_DEBUG("irq_nr=%d breadcrumb=%d\n", irq_nr,
294 READ_BREADCRUMB(dev_priv));
295
296- if (READ_BREADCRUMB(dev_priv) >= irq_nr)
297+ if (READ_BREADCRUMB(dev_priv) >= irq_nr) {
298+ dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
299 return 0;
300+ }
301
302 dev_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT;
303
304+ i915_user_irq_get(dev);
305 DRM_WAIT_ON(ret, dev_priv->irq_queue, 3 * DRM_HZ,
306 READ_BREADCRUMB(dev_priv) >= irq_nr);
307+ i915_user_irq_put(dev);
308
309 if (ret == -EBUSY) {
310 DRM_ERROR("EBUSY -- rec: %d emitted: %d\n",
311@@ -413,20 +467,6 @@ int i915_irq_wait(struct drm_device *dev
312 return i915_wait_irq(dev, irqwait->irq_seq);
313 }
314
315-static void i915_enable_interrupt (struct drm_device *dev)
316-{
317- drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
318- u16 flag;
319-
320- flag = 0;
321- if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_A)
322- flag |= I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT;
323- if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_B)
324- flag |= I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
325-
326- I915_WRITE16(IER, I915_USER_INTERRUPT | flag);
327-}
328-
329 /* Set the vblank monitor pipe
330 */
331 int i915_vblank_pipe_set(struct drm_device *dev, void *data,
332@@ -434,6 +474,7 @@ int i915_vblank_pipe_set(struct drm_devi
333 {
334 drm_i915_private_t *dev_priv = dev->dev_private;
335 drm_i915_vblank_pipe_t *pipe = data;
336+ u32 enable_mask = 0, disable_mask = 0;
337
338 if (!dev_priv) {
339 DRM_ERROR("called with no initialization\n");
340@@ -445,9 +486,20 @@ int i915_vblank_pipe_set(struct drm_devi
341 return -EINVAL;
342 }
343
344- dev_priv->vblank_pipe = pipe->pipe;
345+ if (pipe->pipe & DRM_I915_VBLANK_PIPE_A)
346+ enable_mask |= I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT;
347+ else
348+ disable_mask |= I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT;
349+
350+ if (pipe->pipe & DRM_I915_VBLANK_PIPE_B)
351+ enable_mask |= I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
352+ else
353+ disable_mask |= I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
354
355- i915_enable_interrupt (dev);
356+ i915_enable_irq(dev_priv, enable_mask);
357+ i915_disable_irq(dev_priv, disable_mask);
358+
359+ dev_priv->vblank_pipe = pipe->pipe;
360
361 return 0;
362 }
363@@ -464,7 +516,7 @@ int i915_vblank_pipe_get(struct drm_devi
364 return -EINVAL;
365 }
366
367- flag = I915_READ(IER);
368+ flag = I915_READ(IMR);
369 pipe->pipe = 0;
370 if (flag & I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT)
371 pipe->pipe |= DRM_I915_VBLANK_PIPE_A;
372@@ -586,9 +638,9 @@ void i915_driver_irq_preinstall(struct d
373 {
374 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
375
376- I915_WRITE16(HWSTAM, 0xfffe);
377- I915_WRITE16(IMR, 0x0);
378- I915_WRITE16(IER, 0x0);
379+ I915_WRITE(HWSTAM, 0xfffe);
380+ I915_WRITE(IMR, 0x0);
381+ I915_WRITE(IER, 0x0);
382 }
383
384 void i915_driver_irq_postinstall(struct drm_device * dev)
385@@ -601,7 +653,18 @@ void i915_driver_irq_postinstall(struct
386
387 if (!dev_priv->vblank_pipe)
388 dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A;
389- i915_enable_interrupt(dev);
390+
391+ /* Set initial unmasked IRQs to just the selected vblank pipes. */
392+ dev_priv->irq_mask_reg = ~0;
393+ if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_A)
394+ dev_priv->irq_mask_reg &= ~I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT;
395+ if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_B)
396+ dev_priv->irq_mask_reg &= ~I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
397+
398+ I915_WRITE(IMR, dev_priv->irq_mask_reg);
399+ I915_WRITE(IER, I915_INTERRUPT_ENABLE_MASK);
400+ (void) I915_READ(IER);
401+
402 DRM_INIT_WAITQUEUE(&dev_priv->irq_queue);
403 }
404
405@@ -613,10 +676,10 @@ void i915_driver_irq_uninstall(struct dr
406 if (!dev_priv)
407 return;
408
409- I915_WRITE16(HWSTAM, 0xffff);
410- I915_WRITE16(IMR, 0xffff);
411- I915_WRITE16(IER, 0x0);
412+ I915_WRITE(HWSTAM, 0xffff);
413+ I915_WRITE(IMR, 0xffff);
414+ I915_WRITE(IER, 0x0);
415
416- temp = I915_READ16(IIR);
417- I915_WRITE16(IIR, temp);
418+ temp = I915_READ(IIR);
419+ I915_WRITE(IIR, temp);
420 }
421
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27-rc1/0004_i915.Track_progress_inside_of_batchbuffers_for_determining_wedgedness.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc1/0004_i915.Track_progress_inside_of_batchbuffers_for_determining_wedgedness.patch
new file mode 100644
index 0000000000..c391d16b76
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc1/0004_i915.Track_progress_inside_of_batchbuffers_for_determining_wedgedness.patch
@@ -0,0 +1,47 @@
1From: Keith Packard <keithp@keithp.com>
2Date: Wed, 30 Jul 2008 19:21:20 +0000 (-0700)
3Subject: i915: Track progress inside of batchbuffers for determining wedgedness.
4X-Git-Tag: v2.6.12-rc2
5X-Git-Url: http://gitweb.freedesktop.org/?p=users/anholt/anholt/linux-2.6.git;a=commitdiff;h=f0740db2246e4217384e8de32de6ebb4fbd807c9
6
7i915: Track progress inside of batchbuffers for determining wedgedness.
8
9This avoids early termination for long-running commands.
10
11Signed-off-by: Eric Anholt <eric@anholt.net>
12---
13
14--- a/drivers/gpu/drm/i915/i915_dma.c
15+++ b/drivers/gpu/drm/i915/i915_dma.c
16@@ -40,11 +40,15 @@ int i915_wait_ring(struct drm_device * d
17 {
18 drm_i915_private_t *dev_priv = dev->dev_private;
19 drm_i915_ring_buffer_t *ring = &(dev_priv->ring);
20+ u32 acthd_reg = IS_I965G(dev) ? ACTHD_I965 : ACTHD;
21+ u32 last_acthd = I915_READ(acthd_reg);
22+ u32 acthd;
23 u32 last_head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
24 int i;
25
26- for (i = 0; i < 10000; i++) {
27+ for (i = 0; i < 100000; i++) {
28 ring->head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
29+ acthd = I915_READ(acthd_reg);
30 ring->space = ring->head - (ring->tail + 8);
31 if (ring->space < 0)
32 ring->space += ring->Size;
33@@ -55,8 +59,13 @@ int i915_wait_ring(struct drm_device * d
34
35 if (ring->head != last_head)
36 i = 0;
37+ if (acthd != last_acthd)
38+ i = 0;
39
40 last_head = ring->head;
41+ last_acthd = acthd;
42+ msleep_interruptible(10);
43+
44 }
45
46 return -EBUSY;
47
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27-rc1/0005_i915.remove_settable_use_mi_batchbuffer_start.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc1/0005_i915.remove_settable_use_mi_batchbuffer_start.patch
new file mode 100644
index 0000000000..12362fef5a
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc1/0005_i915.remove_settable_use_mi_batchbuffer_start.patch
@@ -0,0 +1,59 @@
1From: Keith Packard <keithp@keithp.com>
2Date: Wed, 30 Jul 2008 19:28:47 +0000 (-0700)
3Subject: i915: remove settable use_mi_batchbuffer_start
4X-Git-Tag: v2.6.12-rc2
5X-Git-Url: http://gitweb.freedesktop.org/?p=users/anholt/anholt/linux-2.6.git;a=commitdiff;h=6fcd9a69a91c53d733870df20e095eea2b73620c
6
7i915: remove settable use_mi_batchbuffer_start
8
9The driver can know what hardware requires MI_BATCH_BUFFER vs
10MI_BATCH_BUFFER_START; there's no reason to let user mode configure this.
11
12Signed-off-by: Eric Anholt <eric@anholt.net>
13---
14
15--- a/drivers/gpu/drm/i915/i915_dma.c
16+++ b/drivers/gpu/drm/i915/i915_dma.c
17@@ -159,13 +159,6 @@ static int i915_initialize(struct drm_de
18 dev_priv->current_page = 0;
19 dev_priv->sarea_priv->pf_current_page = dev_priv->current_page;
20
21- /* We are using separate values as placeholders for mechanisms for
22- * private backbuffer/depthbuffer usage.
23- */
24- dev_priv->use_mi_batchbuffer_start = 0;
25- if (IS_I965G(dev)) /* 965 doesn't support older method */
26- dev_priv->use_mi_batchbuffer_start = 1;
27-
28 /* Allow hardware batchbuffers unless told otherwise.
29 */
30 dev_priv->allow_batchbuffer = 1;
31@@ -486,7 +479,7 @@ static int i915_dispatch_batchbuffer(str
32 return ret;
33 }
34
35- if (dev_priv->use_mi_batchbuffer_start) {
36+ if (!IS_I830(dev) && !IS_845G(dev)) {
37 BEGIN_LP_RING(2);
38 if (IS_I965G(dev)) {
39 OUT_RING(MI_BATCH_BUFFER_START | (2 << 6) | MI_BATCH_NON_SECURE_I965);
40@@ -697,8 +690,6 @@ static int i915_setparam(struct drm_devi
41
42 switch (param->param) {
43 case I915_SETPARAM_USE_MI_BATCHBUFFER_START:
44- if (!IS_I965G(dev))
45- dev_priv->use_mi_batchbuffer_start = param->value;
46 break;
47 case I915_SETPARAM_TEX_LRU_LOG_GRANULARITY:
48 dev_priv->tex_lru_log_granularity = param->value;
49--- a/drivers/gpu/drm/i915/i915_drv.h
50+++ b/drivers/gpu/drm/i915/i915_drv.h
51@@ -99,7 +99,6 @@ typedef struct drm_i915_private {
52 int front_offset;
53 int current_page;
54 int page_flipping;
55- int use_mi_batchbuffer_start;
56
57 wait_queue_head_t irq_queue;
58 atomic_t irq_received;
59
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27-rc1/0006_i915.Ignore_X_server_provided_mmio_address.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc1/0006_i915.Ignore_X_server_provided_mmio_address.patch
new file mode 100644
index 0000000000..397f683af7
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc1/0006_i915.Ignore_X_server_provided_mmio_address.patch
@@ -0,0 +1,42 @@
1From: Keith Packard <keithp@keithp.com>
2Date: Wed, 30 Jul 2008 19:36:08 +0000 (-0700)
3Subject: i915: Ignore X server provided mmio address
4X-Git-Tag: v2.6.12-rc2
5X-Git-Url: http://gitweb.freedesktop.org/?p=users/anholt/anholt/linux-2.6.git;a=commitdiff;h=5d34a0e06e6e70b01ee070094322695b9e3f0029
6
7i915: Ignore X server provided mmio address
8
9It is already correctly detected by the kernel for use in suspend/resume.
10
11Signed-off-by: Eric Anholt <eric@anholt.net>
12---
13
14--- a/drivers/gpu/drm/i915/i915_dma.c
15+++ b/drivers/gpu/drm/i915/i915_dma.c
16@@ -121,13 +121,6 @@ static int i915_initialize(struct drm_de
17 return -EINVAL;
18 }
19
20- dev_priv->mmio_map = drm_core_findmap(dev, init->mmio_offset);
21- if (!dev_priv->mmio_map) {
22- i915_dma_cleanup(dev);
23- DRM_ERROR("can not find mmio map!\n");
24- return -EINVAL;
25- }
26-
27 dev_priv->sarea_priv = (drm_i915_sarea_t *)
28 ((u8 *) dev_priv->sarea->handle + init->sarea_priv_offset);
29
30@@ -194,11 +187,6 @@ static int i915_dma_resume(struct drm_de
31 return -EINVAL;
32 }
33
34- if (!dev_priv->mmio_map) {
35- DRM_ERROR("can not find mmio map!\n");
36- return -EINVAL;
37- }
38-
39 if (dev_priv->ring.map.handle == NULL) {
40 DRM_ERROR("can not ioremap virtual address for"
41 " ring buffer\n");
42
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27-rc1/0007_i915.Initialize_hardware_status_page_at_device_load_when_possible.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc1/0007_i915.Initialize_hardware_status_page_at_device_load_when_possible.patch
new file mode 100644
index 0000000000..cf646f01c7
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc1/0007_i915.Initialize_hardware_status_page_at_device_load_when_possible.patch
@@ -0,0 +1,138 @@
1From: Keith Packard <keithp@keithp.com>
2Date: Wed, 30 Jul 2008 20:03:43 +0000 (-0700)
3Subject: i915: Initialize hardware status page at device load when possible.
4X-Git-Tag: v2.6.12-rc2
5X-Git-Url: http://gitweb.freedesktop.org/?p=users/anholt/anholt/linux-2.6.git;a=commitdiff;h=ddb354254f88965f5f057e67ef775fbb4b35fef8
6
7i915: Initialize hardware status page at device load when possible.
8
9Some chips were unstable with repeated setup/teardown of the hardware status
10page.
11
12Signed-off-by: Eric Anholt <eric@anholt.net>
13---
14
15--- a/drivers/gpu/drm/i915/i915_dma.c
16+++ b/drivers/gpu/drm/i915/i915_dma.c
17@@ -71,6 +71,52 @@ int i915_wait_ring(struct drm_device * d
18 return -EBUSY;
19 }
20
21+/**
22+ * Sets up the hardware status page for devices that need a physical address
23+ * in the register.
24+ */
25+int i915_init_phys_hws(struct drm_device *dev)
26+{
27+ drm_i915_private_t *dev_priv = dev->dev_private;
28+ /* Program Hardware Status Page */
29+ dev_priv->status_page_dmah =
30+ drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 0xffffffff);
31+
32+ if (!dev_priv->status_page_dmah) {
33+ DRM_ERROR("Can not allocate hardware status page\n");
34+ return -ENOMEM;
35+ }
36+ dev_priv->hw_status_page = dev_priv->status_page_dmah->vaddr;
37+ dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr;
38+
39+ memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
40+
41+ I915_WRITE(HWS_PGA, dev_priv->dma_status_page);
42+ DRM_DEBUG("Enabled hardware status page\n");
43+ return 0;
44+}
45+
46+/**
47+ * Frees the hardware status page, whether it's a physical address or a virtual
48+ * address set up by the X Server.
49+ */
50+void i915_free_hws(struct drm_device *dev)
51+{
52+ drm_i915_private_t *dev_priv = dev->dev_private;
53+ if (dev_priv->status_page_dmah) {
54+ drm_pci_free(dev, dev_priv->status_page_dmah);
55+ dev_priv->status_page_dmah = NULL;
56+ }
57+
58+ if (dev_priv->status_gfx_addr) {
59+ dev_priv->status_gfx_addr = 0;
60+ drm_core_ioremapfree(&dev_priv->hws_map, dev);
61+ }
62+
63+ /* Need to rewrite hardware status page */
64+ I915_WRITE(HWS_PGA, 0x1ffff000);
65+}
66+
67 void i915_kernel_lost_context(struct drm_device * dev)
68 {
69 drm_i915_private_t *dev_priv = dev->dev_private;
70@@ -103,18 +149,9 @@ static int i915_dma_cleanup(struct drm_d
71 dev_priv->ring.map.size = 0;
72 }
73
74- if (dev_priv->status_page_dmah) {
75- drm_pci_free(dev, dev_priv->status_page_dmah);
76- dev_priv->status_page_dmah = NULL;
77- /* Need to rewrite hardware status page */
78- I915_WRITE(HWS_PGA, 0x1ffff000);
79- }
80-
81- if (dev_priv->status_gfx_addr) {
82- dev_priv->status_gfx_addr = 0;
83- drm_core_ioremapfree(&dev_priv->hws_map, dev);
84- I915_WRITE(HWS_PGA, 0x1ffff000);
85- }
86+ /* Clear the HWS virtual address at teardown */
87+ if (I915_NEED_GFX_HWS(dev))
88+ i915_free_hws(dev);
89
90 return 0;
91 }
92@@ -165,23 +202,6 @@ static int i915_initialize(struct drm_de
93 */
94 dev_priv->allow_batchbuffer = 1;
95
96- /* Program Hardware Status Page */
97- if (!I915_NEED_GFX_HWS(dev)) {
98- dev_priv->status_page_dmah =
99- drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 0xffffffff);
100-
101- if (!dev_priv->status_page_dmah) {
102- i915_dma_cleanup(dev);
103- DRM_ERROR("Can not allocate hardware status page\n");
104- return -ENOMEM;
105- }
106- dev_priv->hw_status_page = dev_priv->status_page_dmah->vaddr;
107- dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr;
108-
109- memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
110- I915_WRITE(HWS_PGA, dev_priv->dma_status_page);
111- }
112- DRM_DEBUG("Enabled hardware status page\n");
113 return 0;
114 }
115
116@@ -773,6 +793,12 @@ int i915_driver_load(struct drm_device *
117 _DRM_KERNEL | _DRM_DRIVER,
118 &dev_priv->mmio_map);
119
120+ /* Init HWS */
121+ if (!I915_NEED_GFX_HWS(dev)) {
122+ ret = i915_init_phys_hws(dev);
123+ if (ret != 0)
124+ return ret;
125+ }
126
127 /* On the 945G/GM, the chipset reports the MSI capability on the
128 * integrated graphics even though the support isn't actually there
129@@ -796,6 +822,8 @@ int i915_driver_unload(struct drm_device
130 if (dev->pdev->msi_enabled)
131 pci_disable_msi(dev->pdev);
132
133+ i915_free_hws(dev);
134+
135 if (dev_priv->mmio_map)
136 drm_rmmap(dev, dev_priv->mmio_map);
137
138
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27-rc1/0008_drm.Add_GEM_graphics_execution_manager_to_i915_driver.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc1/0008_drm.Add_GEM_graphics_execution_manager_to_i915_driver.patch
new file mode 100644
index 0000000000..e7ae851c4c
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc1/0008_drm.Add_GEM_graphics_execution_manager_to_i915_driver.patch
@@ -0,0 +1,5453 @@
1From: Eric Anholt <eric@anholt.net>
2Date: Wed, 30 Jul 2008 19:06:12 +0000 (-0700)
3Subject: drm: Add GEM ("graphics execution manager") to i915 driver.
4X-Git-Tag: v2.6.12-rc2
5X-Git-Url: http://gitweb.freedesktop.org/?p=users/anholt/anholt/linux-2.6.git;a=commitdiff;h=drm-gem-merge
6
7drm: Add GEM ("graphics execution manager") to i915 driver.
8
9GEM allows the creation of persistent buffer objects accessible by the
10graphics device through new ioctls for managing execution of commands on the
11device. The userland API is almost entirely driver-specific to ensure that
12any driver building on this model can easily map the interface to individual
13driver requirements.
14
15GEM is used by the 2d driver for managing its internal state allocations and
16will be used for pixmap storage to reduce memory consumption and enable
17zero-copy GLX_EXT_texture_from_pixmap, and in the 3d driver is used to enable
18GL_EXT_framebuffer_object and GL_ARB_pixel_buffer_object.
19
20Signed-off-by: Eric Anholt <eric@anholt.net>
21---
22
23--- a/drivers/gpu/drm/Makefile
24+++ b/drivers/gpu/drm/Makefile
25@@ -4,8 +4,9 @@
26
27 ccflags-y := -Iinclude/drm
28
29-drm-y := drm_auth.o drm_bufs.o drm_context.o drm_dma.o drm_drawable.o \
30- drm_drv.o drm_fops.o drm_ioctl.o drm_irq.o \
31+drm-y := drm_auth.o drm_bufs.o drm_cache.o \
32+ drm_context.o drm_dma.o drm_drawable.o \
33+ drm_drv.o drm_fops.o drm_gem.o drm_ioctl.o drm_irq.o \
34 drm_lock.o drm_memory.o drm_proc.o drm_stub.o drm_vm.o \
35 drm_agpsupport.o drm_scatter.o ati_pcigart.o drm_pci.o \
36 drm_sysfs.o drm_hashtab.o drm_sman.o drm_mm.o
37--- a/drivers/gpu/drm/drm_agpsupport.c
38+++ b/drivers/gpu/drm/drm_agpsupport.c
39@@ -33,6 +33,7 @@
40
41 #include "drmP.h"
42 #include <linux/module.h>
43+#include <asm/agp.h>
44
45 #if __OS_HAS_AGP
46
47@@ -452,4 +453,52 @@ int drm_agp_unbind_memory(DRM_AGP_MEM *
48 return agp_unbind_memory(handle);
49 }
50
51-#endif /* __OS_HAS_AGP */
52+/**
53+ * Binds a collection of pages into AGP memory at the given offset, returning
54+ * the AGP memory structure containing them.
55+ *
56+ * No reference is held on the pages during this time -- it is up to the
57+ * caller to handle that.
58+ */
59+DRM_AGP_MEM *
60+drm_agp_bind_pages(struct drm_device *dev,
61+ struct page **pages,
62+ unsigned long num_pages,
63+ uint32_t gtt_offset)
64+{
65+ DRM_AGP_MEM *mem;
66+ int ret, i;
67+
68+ DRM_DEBUG("\n");
69+
70+ mem = drm_agp_allocate_memory(dev->agp->bridge, num_pages,
71+ AGP_USER_MEMORY);
72+ if (mem == NULL) {
73+ DRM_ERROR("Failed to allocate memory for %ld pages\n",
74+ num_pages);
75+ return NULL;
76+ }
77+
78+ for (i = 0; i < num_pages; i++)
79+ mem->memory[i] = phys_to_gart(page_to_phys(pages[i]));
80+ mem->page_count = num_pages;
81+
82+ mem->is_flushed = true;
83+ ret = drm_agp_bind_memory(mem, gtt_offset / PAGE_SIZE);
84+ if (ret != 0) {
85+ DRM_ERROR("Failed to bind AGP memory: %d\n", ret);
86+ agp_free_memory(mem);
87+ return NULL;
88+ }
89+
90+ return mem;
91+}
92+EXPORT_SYMBOL(drm_agp_bind_pages);
93+
94+void drm_agp_chipset_flush(struct drm_device *dev)
95+{
96+ agp_flush_chipset(dev->agp->bridge);
97+}
98+EXPORT_SYMBOL(drm_agp_chipset_flush);
99+
100+#endif /* __OS_HAS_AGP */
101--- /dev/null
102+++ b/drivers/gpu/drm/drm_cache.c
103@@ -0,0 +1,76 @@
104+/**************************************************************************
105+ *
106+ * Copyright (c) 2006-2007 Tungsten Graphics, Inc., Cedar Park, TX., USA
107+ * All Rights Reserved.
108+ *
109+ * Permission is hereby granted, free of charge, to any person obtaining a
110+ * copy of this software and associated documentation files (the
111+ * "Software"), to deal in the Software without restriction, including
112+ * without limitation the rights to use, copy, modify, merge, publish,
113+ * distribute, sub license, and/or sell copies of the Software, and to
114+ * permit persons to whom the Software is furnished to do so, subject to
115+ * the following conditions:
116+ *
117+ * The above copyright notice and this permission notice (including the
118+ * next paragraph) shall be included in all copies or substantial portions
119+ * of the Software.
120+ *
121+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
122+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
123+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
124+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
125+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
126+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
127+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
128+ *
129+ **************************************************************************/
130+/*
131+ * Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com>
132+ */
133+
134+#include "drmP.h"
135+
136+#if defined(CONFIG_X86)
137+static void
138+drm_clflush_page(struct page *page)
139+{
140+ uint8_t *page_virtual;
141+ unsigned int i;
142+
143+ if (unlikely(page == NULL))
144+ return;
145+
146+ page_virtual = kmap_atomic(page, KM_USER0);
147+ for (i = 0; i < PAGE_SIZE; i += boot_cpu_data.x86_clflush_size)
148+ clflush(page_virtual + i);
149+ kunmap_atomic(page_virtual, KM_USER0);
150+}
151+#endif
152+
153+static void
154+drm_clflush_ipi_handler(void *null)
155+{
156+ wbinvd();
157+}
158+
159+void
160+drm_clflush_pages(struct page *pages[], unsigned long num_pages)
161+{
162+
163+#if defined(CONFIG_X86)
164+ if (cpu_has_clflush) {
165+ unsigned long i;
166+
167+ mb();
168+ for (i = 0; i < num_pages; ++i)
169+ drm_clflush_page(*pages++);
170+ mb();
171+
172+ return;
173+ }
174+#endif
175+
176+ if (on_each_cpu(drm_clflush_ipi_handler, NULL, 1) != 0)
177+ DRM_ERROR("Timed out waiting for cache flush.\n");
178+}
179+EXPORT_SYMBOL(drm_clflush_pages);
180--- a/drivers/gpu/drm/drm_drv.c
181+++ b/drivers/gpu/drm/drm_drv.c
182@@ -117,6 +117,10 @@ static struct drm_ioctl_desc drm_ioctls[
183 DRM_IOCTL_DEF(DRM_IOCTL_WAIT_VBLANK, drm_wait_vblank, 0),
184
185 DRM_IOCTL_DEF(DRM_IOCTL_UPDATE_DRAW, drm_update_drawable_info, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
186+
187+ DRM_IOCTL_DEF(DRM_IOCTL_GEM_CLOSE, drm_gem_close_ioctl, 0),
188+ DRM_IOCTL_DEF(DRM_IOCTL_GEM_FLINK, drm_gem_flink_ioctl, DRM_AUTH),
189+ DRM_IOCTL_DEF(DRM_IOCTL_GEM_OPEN, drm_gem_open_ioctl, DRM_AUTH),
190 };
191
192 #define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls )
193--- a/drivers/gpu/drm/drm_fops.c
194+++ b/drivers/gpu/drm/drm_fops.c
195@@ -256,6 +256,9 @@ static int drm_open_helper(struct inode
196
197 INIT_LIST_HEAD(&priv->lhead);
198
199+ if (dev->driver->driver_features & DRIVER_GEM)
200+ drm_gem_open(dev, priv);
201+
202 if (dev->driver->open) {
203 ret = dev->driver->open(dev, priv);
204 if (ret < 0)
205@@ -400,6 +403,9 @@ int drm_release(struct inode *inode, str
206 dev->driver->reclaim_buffers(dev, file_priv);
207 }
208
209+ if (dev->driver->driver_features & DRIVER_GEM)
210+ drm_gem_release(dev, file_priv);
211+
212 drm_fasync(-1, filp, 0);
213
214 mutex_lock(&dev->ctxlist_mutex);
215--- /dev/null
216+++ b/drivers/gpu/drm/drm_gem.c
217@@ -0,0 +1,420 @@
218+/*
219+ * Copyright © 2008 Intel Corporation
220+ *
221+ * Permission is hereby granted, free of charge, to any person obtaining a
222+ * copy of this software and associated documentation files (the "Software"),
223+ * to deal in the Software without restriction, including without limitation
224+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
225+ * and/or sell copies of the Software, and to permit persons to whom the
226+ * Software is furnished to do so, subject to the following conditions:
227+ *
228+ * The above copyright notice and this permission notice (including the next
229+ * paragraph) shall be included in all copies or substantial portions of the
230+ * Software.
231+ *
232+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
233+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
234+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
235+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
236+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
237+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
238+ * IN THE SOFTWARE.
239+ *
240+ * Authors:
241+ * Eric Anholt <eric@anholt.net>
242+ *
243+ */
244+
245+#include <linux/types.h>
246+#include <linux/slab.h>
247+#include <linux/mm.h>
248+#include <linux/uaccess.h>
249+#include <linux/fs.h>
250+#include <linux/file.h>
251+#include <linux/module.h>
252+#include <linux/mman.h>
253+#include <linux/pagemap.h>
254+#include "drmP.h"
255+
256+/** @file drm_gem.c
257+ *
258+ * This file provides some of the base ioctls and library routines for
259+ * the graphics memory manager implemented by each device driver.
260+ *
261+ * Because various devices have different requirements in terms of
262+ * synchronization and migration strategies, implementing that is left up to
263+ * the driver, and all that the general API provides should be generic --
264+ * allocating objects, reading/writing data with the cpu, freeing objects.
265+ * Even there, platform-dependent optimizations for reading/writing data with
266+ * the CPU mean we'll likely hook those out to driver-specific calls. However,
267+ * the DRI2 implementation wants to have at least allocate/mmap be generic.
268+ *
269+ * The goal was to have swap-backed object allocation managed through
270+ * struct file. However, file descriptors as handles to a struct file have
271+ * two major failings:
272+ * - Process limits prevent more than 1024 or so being used at a time by
273+ * default.
274+ * - Inability to allocate high fds will aggravate the X Server's select()
275+ * handling, and likely that of many GL client applications as well.
276+ *
277+ * This led to a plan of using our own integer IDs (called handles, following
278+ * DRM terminology) to mimic fds, and implement the fd syscalls we need as
279+ * ioctls. The objects themselves will still include the struct file so
280+ * that we can transition to fds if the required kernel infrastructure shows
281+ * up at a later date, and as our interface with shmfs for memory allocation.
282+ */
283+
284+/**
285+ * Initialize the GEM device fields
286+ */
287+
288+int
289+drm_gem_init(struct drm_device *dev)
290+{
291+ spin_lock_init(&dev->object_name_lock);
292+ idr_init(&dev->object_name_idr);
293+ atomic_set(&dev->object_count, 0);
294+ atomic_set(&dev->object_memory, 0);
295+ atomic_set(&dev->pin_count, 0);
296+ atomic_set(&dev->pin_memory, 0);
297+ atomic_set(&dev->gtt_count, 0);
298+ atomic_set(&dev->gtt_memory, 0);
299+ return 0;
300+}
301+
302+/**
303+ * Allocate a GEM object of the specified size with shmfs backing store
304+ */
305+struct drm_gem_object *
306+drm_gem_object_alloc(struct drm_device *dev, size_t size)
307+{
308+ struct drm_gem_object *obj;
309+
310+ BUG_ON((size & (PAGE_SIZE - 1)) != 0);
311+
312+ obj = kcalloc(1, sizeof(*obj), GFP_KERNEL);
313+
314+ obj->dev = dev;
315+ obj->filp = shmem_file_setup("drm mm object", size, 0);
316+ if (IS_ERR(obj->filp)) {
317+ kfree(obj);
318+ return NULL;
319+ }
320+
321+ kref_init(&obj->refcount);
322+ kref_init(&obj->handlecount);
323+ obj->size = size;
324+ if (dev->driver->gem_init_object != NULL &&
325+ dev->driver->gem_init_object(obj) != 0) {
326+ fput(obj->filp);
327+ kfree(obj);
328+ return NULL;
329+ }
330+ atomic_inc(&dev->object_count);
331+ atomic_add(obj->size, &dev->object_memory);
332+ return obj;
333+}
334+EXPORT_SYMBOL(drm_gem_object_alloc);
335+
336+/**
337+ * Removes the mapping from handle to filp for this object.
338+ */
339+static int
340+drm_gem_handle_delete(struct drm_file *filp, int handle)
341+{
342+ struct drm_device *dev;
343+ struct drm_gem_object *obj;
344+
345+ /* This is gross. The idr system doesn't let us try a delete and
346+ * return an error code. It just spews if you fail at deleting.
347+ * So, we have to grab a lock around finding the object and then
348+ * doing the delete on it and dropping the refcount, or the user
349+ * could race us to double-decrement the refcount and cause a
350+ * use-after-free later. Given the frequency of our handle lookups,
351+ * we may want to use ida for number allocation and a hash table
352+ * for the pointers, anyway.
353+ */
354+ spin_lock(&filp->table_lock);
355+
356+ /* Check if we currently have a reference on the object */
357+ obj = idr_find(&filp->object_idr, handle);
358+ if (obj == NULL) {
359+ spin_unlock(&filp->table_lock);
360+ return -EINVAL;
361+ }
362+ dev = obj->dev;
363+
364+ /* Release reference and decrement refcount. */
365+ idr_remove(&filp->object_idr, handle);
366+ spin_unlock(&filp->table_lock);
367+
368+ mutex_lock(&dev->struct_mutex);
369+ drm_gem_object_handle_unreference(obj);
370+ mutex_unlock(&dev->struct_mutex);
371+
372+ return 0;
373+}
374+
375+/**
376+ * Create a handle for this object. This adds a handle reference
377+ * to the object, which includes a regular reference count. Callers
378+ * will likely want to dereference the object afterwards.
379+ */
380+int
381+drm_gem_handle_create(struct drm_file *file_priv,
382+ struct drm_gem_object *obj,
383+ int *handlep)
384+{
385+ int ret;
386+
387+ /*
388+ * Get the user-visible handle using idr.
389+ */
390+again:
391+ /* ensure there is space available to allocate a handle */
392+ if (idr_pre_get(&file_priv->object_idr, GFP_KERNEL) == 0)
393+ return -ENOMEM;
394+
395+ /* do the allocation under our spinlock */
396+ spin_lock(&file_priv->table_lock);
397+ ret = idr_get_new_above(&file_priv->object_idr, obj, 1, handlep);
398+ spin_unlock(&file_priv->table_lock);
399+ if (ret == -EAGAIN)
400+ goto again;
401+
402+ if (ret != 0)
403+ return ret;
404+
405+ drm_gem_object_handle_reference(obj);
406+ return 0;
407+}
408+EXPORT_SYMBOL(drm_gem_handle_create);
409+
410+/** Returns a reference to the object named by the handle. */
411+struct drm_gem_object *
412+drm_gem_object_lookup(struct drm_device *dev, struct drm_file *filp,
413+ int handle)
414+{
415+ struct drm_gem_object *obj;
416+
417+ spin_lock(&filp->table_lock);
418+
419+ /* Check if we currently have a reference on the object */
420+ obj = idr_find(&filp->object_idr, handle);
421+ if (obj == NULL) {
422+ spin_unlock(&filp->table_lock);
423+ return NULL;
424+ }
425+
426+ drm_gem_object_reference(obj);
427+
428+ spin_unlock(&filp->table_lock);
429+
430+ return obj;
431+}
432+EXPORT_SYMBOL(drm_gem_object_lookup);
433+
434+/**
435+ * Releases the handle to an mm object.
436+ */
437+int
438+drm_gem_close_ioctl(struct drm_device *dev, void *data,
439+ struct drm_file *file_priv)
440+{
441+ struct drm_gem_close *args = data;
442+ int ret;
443+
444+ if (!(dev->driver->driver_features & DRIVER_GEM))
445+ return -ENODEV;
446+
447+ ret = drm_gem_handle_delete(file_priv, args->handle);
448+
449+ return ret;
450+}
451+
452+/**
453+ * Create a global name for an object, returning the name.
454+ *
455+ * Note that the name does not hold a reference; when the object
456+ * is freed, the name goes away.
457+ */
458+int
459+drm_gem_flink_ioctl(struct drm_device *dev, void *data,
460+ struct drm_file *file_priv)
461+{
462+ struct drm_gem_flink *args = data;
463+ struct drm_gem_object *obj;
464+ int ret;
465+
466+ if (!(dev->driver->driver_features & DRIVER_GEM))
467+ return -ENODEV;
468+
469+ obj = drm_gem_object_lookup(dev, file_priv, args->handle);
470+ if (obj == NULL)
471+ return -EINVAL;
472+
473+again:
474+ if (idr_pre_get(&dev->object_name_idr, GFP_KERNEL) == 0)
475+ return -ENOMEM;
476+
477+ spin_lock(&dev->object_name_lock);
478+ if (obj->name) {
479+ spin_unlock(&dev->object_name_lock);
480+ return -EEXIST;
481+ }
482+ ret = idr_get_new_above(&dev->object_name_idr, obj, 1,
483+ &obj->name);
484+ spin_unlock(&dev->object_name_lock);
485+ if (ret == -EAGAIN)
486+ goto again;
487+
488+ if (ret != 0) {
489+ mutex_lock(&dev->struct_mutex);
490+ drm_gem_object_unreference(obj);
491+ mutex_unlock(&dev->struct_mutex);
492+ return ret;
493+ }
494+
495+ /*
496+ * Leave the reference from the lookup around as the
497+ * name table now holds one
498+ */
499+ args->name = (uint64_t) obj->name;
500+
501+ return 0;
502+}
503+
504+/**
505+ * Open an object using the global name, returning a handle and the size.
506+ *
507+ * This handle (of course) holds a reference to the object, so the object
508+ * will not go away until the handle is deleted.
509+ */
510+int
511+drm_gem_open_ioctl(struct drm_device *dev, void *data,
512+ struct drm_file *file_priv)
513+{
514+ struct drm_gem_open *args = data;
515+ struct drm_gem_object *obj;
516+ int ret;
517+ int handle;
518+
519+ if (!(dev->driver->driver_features & DRIVER_GEM))
520+ return -ENODEV;
521+
522+ spin_lock(&dev->object_name_lock);
523+ obj = idr_find(&dev->object_name_idr, (int) args->name);
524+ if (obj)
525+ drm_gem_object_reference(obj);
526+ spin_unlock(&dev->object_name_lock);
527+ if (!obj)
528+ return -ENOENT;
529+
530+ ret = drm_gem_handle_create(file_priv, obj, &handle);
531+ mutex_lock(&dev->struct_mutex);
532+ drm_gem_object_unreference(obj);
533+ mutex_unlock(&dev->struct_mutex);
534+ if (ret)
535+ return ret;
536+
537+ args->handle = handle;
538+ args->size = obj->size;
539+
540+ return 0;
541+}
542+
543+/**
544+ * Called at device open time, sets up the structure for handling refcounting
545+ * of mm objects.
546+ */
547+void
548+drm_gem_open(struct drm_device *dev, struct drm_file *file_private)
549+{
550+ idr_init(&file_private->object_idr);
551+ spin_lock_init(&file_private->table_lock);
552+}
553+
554+/**
555+ * Called at device close to release the file's
556+ * handle references on objects.
557+ */
558+static int
559+drm_gem_object_release_handle(int id, void *ptr, void *data)
560+{
561+ struct drm_gem_object *obj = ptr;
562+
563+ drm_gem_object_handle_unreference(obj);
564+
565+ return 0;
566+}
567+
568+/**
569+ * Called at close time when the filp is going away.
570+ *
571+ * Releases any remaining references on objects by this filp.
572+ */
573+void
574+drm_gem_release(struct drm_device *dev, struct drm_file *file_private)
575+{
576+ mutex_lock(&dev->struct_mutex);
577+ idr_for_each(&file_private->object_idr,
578+ &drm_gem_object_release_handle, NULL);
579+
580+ idr_destroy(&file_private->object_idr);
581+ mutex_unlock(&dev->struct_mutex);
582+}
583+
584+/**
585+ * Called after the last reference to the object has been lost.
586+ *
587+ * Frees the object
588+ */
589+void
590+drm_gem_object_free(struct kref *kref)
591+{
592+ struct drm_gem_object *obj = (struct drm_gem_object *) kref;
593+ struct drm_device *dev = obj->dev;
594+
595+ BUG_ON(!mutex_is_locked(&dev->struct_mutex));
596+
597+ if (dev->driver->gem_free_object != NULL)
598+ dev->driver->gem_free_object(obj);
599+
600+ fput(obj->filp);
601+ atomic_dec(&dev->object_count);
602+ atomic_sub(obj->size, &dev->object_memory);
603+ kfree(obj);
604+}
605+EXPORT_SYMBOL(drm_gem_object_free);
606+
607+/**
608+ * Called after the last handle to the object has been closed
609+ *
610+ * Removes any name for the object. Note that this must be
611+ * called before drm_gem_object_free or we'll be touching
612+ * freed memory
613+ */
614+void
615+drm_gem_object_handle_free(struct kref *kref)
616+{
617+ struct drm_gem_object *obj = container_of(kref,
618+ struct drm_gem_object,
619+ handlecount);
620+ struct drm_device *dev = obj->dev;
621+
622+ /* Remove any name for this object */
623+ spin_lock(&dev->object_name_lock);
624+ if (obj->name) {
625+ idr_remove(&dev->object_name_idr, obj->name);
626+ spin_unlock(&dev->object_name_lock);
627+ /*
628+ * The object name held a reference to this object, drop
629+ * that now.
630+ */
631+ drm_gem_object_unreference(obj);
632+ } else
633+ spin_unlock(&dev->object_name_lock);
634+
635+}
636+EXPORT_SYMBOL(drm_gem_object_handle_free);
637+
638--- a/drivers/gpu/drm/drm_memory.c
639+++ b/drivers/gpu/drm/drm_memory.c
640@@ -133,6 +133,7 @@ int drm_free_agp(DRM_AGP_MEM * handle, i
641 {
642 return drm_agp_free_memory(handle) ? 0 : -EINVAL;
643 }
644+EXPORT_SYMBOL(drm_free_agp);
645
646 /** Wrapper around agp_bind_memory() */
647 int drm_bind_agp(DRM_AGP_MEM * handle, unsigned int start)
648@@ -145,6 +146,7 @@ int drm_unbind_agp(DRM_AGP_MEM * handle)
649 {
650 return drm_agp_unbind_memory(handle);
651 }
652+EXPORT_SYMBOL(drm_unbind_agp);
653
654 #else /* __OS_HAS_AGP */
655 static inline void *agp_remap(unsigned long offset, unsigned long size,
656--- a/drivers/gpu/drm/drm_mm.c
657+++ b/drivers/gpu/drm/drm_mm.c
658@@ -169,6 +169,7 @@ struct drm_mm_node *drm_mm_get_block(str
659
660 return child;
661 }
662+EXPORT_SYMBOL(drm_mm_get_block);
663
664 /*
665 * Put a block. Merge with the previous and / or next block if they are free.
666@@ -217,6 +218,7 @@ void drm_mm_put_block(struct drm_mm_node
667 drm_free(cur, sizeof(*cur), DRM_MEM_MM);
668 }
669 }
670+EXPORT_SYMBOL(drm_mm_put_block);
671
672 struct drm_mm_node *drm_mm_search_free(const struct drm_mm * mm,
673 unsigned long size,
674@@ -265,6 +267,7 @@ int drm_mm_clean(struct drm_mm * mm)
675
676 return (head->next->next == head);
677 }
678+EXPORT_SYMBOL(drm_mm_search_free);
679
680 int drm_mm_init(struct drm_mm * mm, unsigned long start, unsigned long size)
681 {
682@@ -273,7 +276,7 @@ int drm_mm_init(struct drm_mm * mm, unsi
683
684 return drm_mm_create_tail_node(mm, start, size);
685 }
686-
687+EXPORT_SYMBOL(drm_mm_init);
688
689 void drm_mm_takedown(struct drm_mm * mm)
690 {
691--- a/drivers/gpu/drm/drm_proc.c
692+++ b/drivers/gpu/drm/drm_proc.c
693@@ -49,6 +49,10 @@ static int drm_queues_info(char *buf, ch
694 int request, int *eof, void *data);
695 static int drm_bufs_info(char *buf, char **start, off_t offset,
696 int request, int *eof, void *data);
697+static int drm_gem_name_info(char *buf, char **start, off_t offset,
698+ int request, int *eof, void *data);
699+static int drm_gem_object_info(char *buf, char **start, off_t offset,
700+ int request, int *eof, void *data);
701 #if DRM_DEBUG_CODE
702 static int drm_vma_info(char *buf, char **start, off_t offset,
703 int request, int *eof, void *data);
704@@ -60,13 +64,16 @@ static int drm_vma_info(char *buf, char
705 static struct drm_proc_list {
706 const char *name; /**< file name */
707 int (*f) (char *, char **, off_t, int, int *, void *); /**< proc callback*/
708+ u32 driver_features; /**< Required driver features for this entry */
709 } drm_proc_list[] = {
710- {"name", drm_name_info},
711- {"mem", drm_mem_info},
712- {"vm", drm_vm_info},
713- {"clients", drm_clients_info},
714- {"queues", drm_queues_info},
715- {"bufs", drm_bufs_info},
716+ {"name", drm_name_info, 0},
717+ {"mem", drm_mem_info, 0},
718+ {"vm", drm_vm_info, 0},
719+ {"clients", drm_clients_info, 0},
720+ {"queues", drm_queues_info, 0},
721+ {"bufs", drm_bufs_info, 0},
722+ {"gem_names", drm_gem_name_info, DRIVER_GEM},
723+ {"gem_objects", drm_gem_object_info, DRIVER_GEM},
724 #if DRM_DEBUG_CODE
725 {"vma", drm_vma_info},
726 #endif
727@@ -90,8 +97,9 @@ static struct drm_proc_list {
728 int drm_proc_init(struct drm_minor *minor, int minor_id,
729 struct proc_dir_entry *root)
730 {
731+ struct drm_device *dev = minor->dev;
732 struct proc_dir_entry *ent;
733- int i, j;
734+ int i, j, ret;
735 char name[64];
736
737 sprintf(name, "%d", minor_id);
738@@ -102,23 +110,42 @@ int drm_proc_init(struct drm_minor *mino
739 }
740
741 for (i = 0; i < DRM_PROC_ENTRIES; i++) {
742+ u32 features = drm_proc_list[i].driver_features;
743+
744+ if (features != 0 &&
745+ (dev->driver->driver_features & features) != features)
746+ continue;
747+
748 ent = create_proc_entry(drm_proc_list[i].name,
749 S_IFREG | S_IRUGO, minor->dev_root);
750 if (!ent) {
751 DRM_ERROR("Cannot create /proc/dri/%s/%s\n",
752 name, drm_proc_list[i].name);
753- for (j = 0; j < i; j++)
754- remove_proc_entry(drm_proc_list[i].name,
755- minor->dev_root);
756- remove_proc_entry(name, root);
757- minor->dev_root = NULL;
758- return -1;
759+ ret = -1;
760+ goto fail;
761 }
762 ent->read_proc = drm_proc_list[i].f;
763 ent->data = minor;
764 }
765
766+ if (dev->driver->proc_init) {
767+ ret = dev->driver->proc_init(minor);
768+ if (ret) {
769+ DRM_ERROR("DRM: Driver failed to initialize "
770+ "/proc/dri.\n");
771+ goto fail;
772+ }
773+ }
774+
775 return 0;
776+ fail:
777+
778+ for (j = 0; j < i; j++)
779+ remove_proc_entry(drm_proc_list[i].name,
780+ minor->dev_root);
781+ remove_proc_entry(name, root);
782+ minor->dev_root = NULL;
783+ return ret;
784 }
785
786 /**
787@@ -133,12 +160,16 @@ int drm_proc_init(struct drm_minor *mino
788 */
789 int drm_proc_cleanup(struct drm_minor *minor, struct proc_dir_entry *root)
790 {
791+ struct drm_device *dev = minor->dev;
792 int i;
793 char name[64];
794
795 if (!root || !minor->dev_root)
796 return 0;
797
798+ if (dev->driver->proc_cleanup)
799+ dev->driver->proc_cleanup(minor);
800+
801 for (i = 0; i < DRM_PROC_ENTRIES; i++)
802 remove_proc_entry(drm_proc_list[i].name, minor->dev_root);
803 sprintf(name, "%d", minor->index);
804@@ -480,6 +511,84 @@ static int drm_clients_info(char *buf, c
805 return ret;
806 }
807
808+struct drm_gem_name_info_data {
809+ int len;
810+ char *buf;
811+ int eof;
812+};
813+
814+static int drm_gem_one_name_info(int id, void *ptr, void *data)
815+{
816+ struct drm_gem_object *obj = ptr;
817+ struct drm_gem_name_info_data *nid = data;
818+
819+ DRM_INFO("name %d size %d\n", obj->name, obj->size);
820+ if (nid->eof)
821+ return 0;
822+
823+ nid->len += sprintf(&nid->buf[nid->len],
824+ "%6d%9d%8d%9d\n",
825+ obj->name, obj->size,
826+ atomic_read(&obj->handlecount.refcount),
827+ atomic_read(&obj->refcount.refcount));
828+ if (nid->len > DRM_PROC_LIMIT) {
829+ nid->eof = 1;
830+ return 0;
831+ }
832+ return 0;
833+}
834+
835+static int drm_gem_name_info(char *buf, char **start, off_t offset,
836+ int request, int *eof, void *data)
837+{
838+ struct drm_minor *minor = (struct drm_minor *) data;
839+ struct drm_device *dev = minor->dev;
840+ struct drm_gem_name_info_data nid;
841+
842+ if (offset > DRM_PROC_LIMIT) {
843+ *eof = 1;
844+ return 0;
845+ }
846+
847+ nid.len = sprintf(buf, " name size handles refcount\n");
848+ nid.buf = buf;
849+ nid.eof = 0;
850+ idr_for_each(&dev->object_name_idr, drm_gem_one_name_info, &nid);
851+
852+ *start = &buf[offset];
853+ *eof = 0;
854+ if (nid.len > request + offset)
855+ return request;
856+ *eof = 1;
857+ return nid.len - offset;
858+}
859+
860+static int drm_gem_object_info(char *buf, char **start, off_t offset,
861+ int request, int *eof, void *data)
862+{
863+ struct drm_minor *minor = (struct drm_minor *) data;
864+ struct drm_device *dev = minor->dev;
865+ int len = 0;
866+
867+ if (offset > DRM_PROC_LIMIT) {
868+ *eof = 1;
869+ return 0;
870+ }
871+
872+ *start = &buf[offset];
873+ *eof = 0;
874+ DRM_PROC_PRINT("%d objects\n", atomic_read(&dev->object_count));
875+ DRM_PROC_PRINT("%d object bytes\n", atomic_read(&dev->object_memory));
876+ DRM_PROC_PRINT("%d pinned\n", atomic_read(&dev->pin_count));
877+ DRM_PROC_PRINT("%d pin bytes\n", atomic_read(&dev->pin_memory));
878+ DRM_PROC_PRINT("%d gtt bytes\n", atomic_read(&dev->gtt_memory));
879+ DRM_PROC_PRINT("%d gtt total\n", dev->gtt_total);
880+ if (len > request + offset)
881+ return request;
882+ *eof = 1;
883+ return len - offset;
884+}
885+
886 #if DRM_DEBUG_CODE
887
888 static int drm__vma_info(char *buf, char **start, off_t offset, int request,
889--- a/drivers/gpu/drm/drm_stub.c
890+++ b/drivers/gpu/drm/drm_stub.c
891@@ -152,6 +152,15 @@ static int drm_fill_in_dev(struct drm_de
892 goto error_out_unreg;
893 }
894
895+ if (driver->driver_features & DRIVER_GEM) {
896+ retcode = drm_gem_init(dev);
897+ if (retcode) {
898+ DRM_ERROR("Cannot initialize graphics execution "
899+ "manager (GEM)\n");
900+ goto error_out_unreg;
901+ }
902+ }
903+
904 return 0;
905
906 error_out_unreg:
907@@ -317,6 +326,7 @@ int drm_put_dev(struct drm_device * dev)
908 int drm_put_minor(struct drm_minor **minor_p)
909 {
910 struct drm_minor *minor = *minor_p;
911+
912 DRM_DEBUG("release secondary minor %d\n", minor->index);
913
914 if (minor->type == DRM_MINOR_LEGACY)
915--- a/drivers/gpu/drm/i915/Makefile
916+++ b/drivers/gpu/drm/i915/Makefile
917@@ -3,7 +3,11 @@
918 # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
919
920 ccflags-y := -Iinclude/drm
921-i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o
922+i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o \
923+ i915_gem.o \
924+ i915_gem_debug.o \
925+ i915_gem_proc.o \
926+ i915_gem_tiling.o
927
928 i915-$(CONFIG_COMPAT) += i915_ioc32.o
929
930--- a/drivers/gpu/drm/i915/i915_dma.c
931+++ b/drivers/gpu/drm/i915/i915_dma.c
932@@ -170,24 +170,31 @@ static int i915_initialize(struct drm_de
933 dev_priv->sarea_priv = (drm_i915_sarea_t *)
934 ((u8 *) dev_priv->sarea->handle + init->sarea_priv_offset);
935
936- dev_priv->ring.Start = init->ring_start;
937- dev_priv->ring.End = init->ring_end;
938- dev_priv->ring.Size = init->ring_size;
939- dev_priv->ring.tail_mask = dev_priv->ring.Size - 1;
940-
941- dev_priv->ring.map.offset = init->ring_start;
942- dev_priv->ring.map.size = init->ring_size;
943- dev_priv->ring.map.type = 0;
944- dev_priv->ring.map.flags = 0;
945- dev_priv->ring.map.mtrr = 0;
946+ if (init->ring_size != 0) {
947+ if (dev_priv->ring.ring_obj != NULL) {
948+ i915_dma_cleanup(dev);
949+ DRM_ERROR("Client tried to initialize ringbuffer in "
950+ "GEM mode\n");
951+ return -EINVAL;
952+ }
953
954- drm_core_ioremap(&dev_priv->ring.map, dev);
955+ dev_priv->ring.Size = init->ring_size;
956+ dev_priv->ring.tail_mask = dev_priv->ring.Size - 1;
957
958- if (dev_priv->ring.map.handle == NULL) {
959- i915_dma_cleanup(dev);
960- DRM_ERROR("can not ioremap virtual address for"
961- " ring buffer\n");
962- return -ENOMEM;
963+ dev_priv->ring.map.offset = init->ring_start;
964+ dev_priv->ring.map.size = init->ring_size;
965+ dev_priv->ring.map.type = 0;
966+ dev_priv->ring.map.flags = 0;
967+ dev_priv->ring.map.mtrr = 0;
968+
969+ drm_core_ioremap(&dev_priv->ring.map, dev);
970+
971+ if (dev_priv->ring.map.handle == NULL) {
972+ i915_dma_cleanup(dev);
973+ DRM_ERROR("can not ioremap virtual address for"
974+ " ring buffer\n");
975+ return -ENOMEM;
976+ }
977 }
978
979 dev_priv->ring.virtual_start = dev_priv->ring.map.handle;
980@@ -377,9 +384,10 @@ static int i915_emit_cmds(struct drm_dev
981 return 0;
982 }
983
984-static int i915_emit_box(struct drm_device * dev,
985- struct drm_clip_rect __user * boxes,
986- int i, int DR1, int DR4)
987+int
988+i915_emit_box(struct drm_device *dev,
989+ struct drm_clip_rect __user *boxes,
990+ int i, int DR1, int DR4)
991 {
992 drm_i915_private_t *dev_priv = dev->dev_private;
993 struct drm_clip_rect box;
994@@ -681,6 +689,9 @@ static int i915_getparam(struct drm_devi
995 case I915_PARAM_LAST_DISPATCH:
996 value = READ_BREADCRUMB(dev_priv);
997 break;
998+ case I915_PARAM_HAS_GEM:
999+ value = 1;
1000+ break;
1001 default:
1002 DRM_ERROR("Unknown parameter %d\n", param->param);
1003 return -EINVAL;
1004@@ -784,6 +795,7 @@ int i915_driver_load(struct drm_device *
1005 memset(dev_priv, 0, sizeof(drm_i915_private_t));
1006
1007 dev->dev_private = (void *)dev_priv;
1008+ dev_priv->dev = dev;
1009
1010 /* Add register map (needed for suspend/resume) */
1011 base = drm_get_resource_start(dev, mmio_bar);
1012@@ -793,6 +805,8 @@ int i915_driver_load(struct drm_device *
1013 _DRM_KERNEL | _DRM_DRIVER,
1014 &dev_priv->mmio_map);
1015
1016+ i915_gem_load(dev);
1017+
1018 /* Init HWS */
1019 if (!I915_NEED_GFX_HWS(dev)) {
1020 ret = i915_init_phys_hws(dev);
1021@@ -833,6 +847,25 @@ int i915_driver_unload(struct drm_device
1022 return 0;
1023 }
1024
1025+int i915_driver_open(struct drm_device *dev, struct drm_file *file_priv)
1026+{
1027+ struct drm_i915_file_private *i915_file_priv;
1028+
1029+ DRM_DEBUG("\n");
1030+ i915_file_priv = (struct drm_i915_file_private *)
1031+ drm_alloc(sizeof(*i915_file_priv), DRM_MEM_FILES);
1032+
1033+ if (!i915_file_priv)
1034+ return -ENOMEM;
1035+
1036+ file_priv->driver_priv = i915_file_priv;
1037+
1038+ i915_file_priv->mm.last_gem_seqno = 0;
1039+ i915_file_priv->mm.last_gem_throttle_seqno = 0;
1040+
1041+ return 0;
1042+}
1043+
1044 void i915_driver_lastclose(struct drm_device * dev)
1045 {
1046 drm_i915_private_t *dev_priv = dev->dev_private;
1047@@ -840,6 +873,8 @@ void i915_driver_lastclose(struct drm_de
1048 if (!dev_priv)
1049 return;
1050
1051+ i915_gem_lastclose(dev);
1052+
1053 if (dev_priv->agp_heap)
1054 i915_mem_takedown(&(dev_priv->agp_heap));
1055
1056@@ -852,6 +887,13 @@ void i915_driver_preclose(struct drm_dev
1057 i915_mem_release(dev, file_priv, dev_priv->agp_heap);
1058 }
1059
1060+void i915_driver_postclose(struct drm_device *dev, struct drm_file *file_priv)
1061+{
1062+ struct drm_i915_file_private *i915_file_priv = file_priv->driver_priv;
1063+
1064+ drm_free(i915_file_priv, sizeof(*i915_file_priv), DRM_MEM_FILES);
1065+}
1066+
1067 struct drm_ioctl_desc i915_ioctls[] = {
1068 DRM_IOCTL_DEF(DRM_I915_INIT, i915_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
1069 DRM_IOCTL_DEF(DRM_I915_FLUSH, i915_flush_ioctl, DRM_AUTH),
1070@@ -870,6 +912,22 @@ struct drm_ioctl_desc i915_ioctls[] = {
1071 DRM_IOCTL_DEF(DRM_I915_GET_VBLANK_PIPE, i915_vblank_pipe_get, DRM_AUTH ),
1072 DRM_IOCTL_DEF(DRM_I915_VBLANK_SWAP, i915_vblank_swap, DRM_AUTH),
1073 DRM_IOCTL_DEF(DRM_I915_HWS_ADDR, i915_set_status_page, DRM_AUTH),
1074+ DRM_IOCTL_DEF(DRM_I915_GEM_INIT, i915_gem_init_ioctl, DRM_AUTH),
1075+ DRM_IOCTL_DEF(DRM_I915_GEM_EXECBUFFER, i915_gem_execbuffer, DRM_AUTH),
1076+ DRM_IOCTL_DEF(DRM_I915_GEM_PIN, i915_gem_pin_ioctl, DRM_AUTH|DRM_ROOT_ONLY),
1077+ DRM_IOCTL_DEF(DRM_I915_GEM_UNPIN, i915_gem_unpin_ioctl, DRM_AUTH|DRM_ROOT_ONLY),
1078+ DRM_IOCTL_DEF(DRM_I915_GEM_BUSY, i915_gem_busy_ioctl, DRM_AUTH),
1079+ DRM_IOCTL_DEF(DRM_I915_GEM_THROTTLE, i915_gem_throttle_ioctl, DRM_AUTH),
1080+ DRM_IOCTL_DEF(DRM_I915_GEM_ENTERVT, i915_gem_entervt_ioctl, DRM_AUTH),
1081+ DRM_IOCTL_DEF(DRM_I915_GEM_LEAVEVT, i915_gem_leavevt_ioctl, DRM_AUTH),
1082+ DRM_IOCTL_DEF(DRM_I915_GEM_CREATE, i915_gem_create_ioctl, 0),
1083+ DRM_IOCTL_DEF(DRM_I915_GEM_PREAD, i915_gem_pread_ioctl, 0),
1084+ DRM_IOCTL_DEF(DRM_I915_GEM_PWRITE, i915_gem_pwrite_ioctl, 0),
1085+ DRM_IOCTL_DEF(DRM_I915_GEM_MMAP, i915_gem_mmap_ioctl, 0),
1086+ DRM_IOCTL_DEF(DRM_I915_GEM_SET_DOMAIN, i915_gem_set_domain_ioctl, 0),
1087+ DRM_IOCTL_DEF(DRM_I915_GEM_SW_FINISH, i915_gem_sw_finish_ioctl, 0),
1088+ DRM_IOCTL_DEF(DRM_I915_GEM_SET_TILING, i915_gem_set_tiling, 0),
1089+ DRM_IOCTL_DEF(DRM_I915_GEM_GET_TILING, i915_gem_get_tiling, 0),
1090 };
1091
1092 int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls);
1093--- a/drivers/gpu/drm/i915/i915_drv.c
1094+++ b/drivers/gpu/drm/i915/i915_drv.c
1095@@ -542,11 +542,13 @@ static struct drm_driver driver = {
1096 .driver_features =
1097 DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | /* DRIVER_USE_MTRR |*/
1098 DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL |
1099- DRIVER_IRQ_VBL2,
1100+ DRIVER_IRQ_VBL2 | DRIVER_GEM,
1101 .load = i915_driver_load,
1102 .unload = i915_driver_unload,
1103+ .open = i915_driver_open,
1104 .lastclose = i915_driver_lastclose,
1105 .preclose = i915_driver_preclose,
1106+ .postclose = i915_driver_postclose,
1107 .suspend = i915_suspend,
1108 .resume = i915_resume,
1109 .device_is_agp = i915_driver_device_is_agp,
1110@@ -559,6 +561,10 @@ static struct drm_driver driver = {
1111 .reclaim_buffers = drm_core_reclaim_buffers,
1112 .get_map_ofs = drm_core_get_map_ofs,
1113 .get_reg_ofs = drm_core_get_reg_ofs,
1114+ .proc_init = i915_gem_proc_init,
1115+ .proc_cleanup = i915_gem_proc_cleanup,
1116+ .gem_init_object = i915_gem_init_object,
1117+ .gem_free_object = i915_gem_free_object,
1118 .ioctls = i915_ioctls,
1119 .fops = {
1120 .owner = THIS_MODULE,
1121--- a/drivers/gpu/drm/i915/i915_drv.h
1122+++ b/drivers/gpu/drm/i915/i915_drv.h
1123@@ -39,7 +39,7 @@
1124
1125 #define DRIVER_NAME "i915"
1126 #define DRIVER_DESC "Intel Graphics"
1127-#define DRIVER_DATE "20060119"
1128+#define DRIVER_DATE "20080730"
1129
1130 /* Interface history:
1131 *
1132@@ -55,16 +55,23 @@
1133 #define DRIVER_MINOR 6
1134 #define DRIVER_PATCHLEVEL 0
1135
1136+#define WATCH_COHERENCY 0
1137+#define WATCH_BUF 0
1138+#define WATCH_EXEC 0
1139+#define WATCH_LRU 0
1140+#define WATCH_RELOC 0
1141+#define WATCH_INACTIVE 0
1142+#define WATCH_PWRITE 0
1143+
1144 typedef struct _drm_i915_ring_buffer {
1145 int tail_mask;
1146- unsigned long Start;
1147- unsigned long End;
1148 unsigned long Size;
1149 u8 *virtual_start;
1150 int head;
1151 int tail;
1152 int space;
1153 drm_local_map_t map;
1154+ struct drm_gem_object *ring_obj;
1155 } drm_i915_ring_buffer_t;
1156
1157 struct mem_block {
1158@@ -83,6 +90,8 @@ typedef struct _drm_i915_vbl_swap {
1159 } drm_i915_vbl_swap_t;
1160
1161 typedef struct drm_i915_private {
1162+ struct drm_device *dev;
1163+
1164 drm_local_map_t *sarea;
1165 drm_local_map_t *mmio_map;
1166
1167@@ -95,6 +104,7 @@ typedef struct drm_i915_private {
1168 unsigned long counter;
1169 unsigned int status_gfx_addr;
1170 drm_local_map_t hws_map;
1171+ struct drm_gem_object *hws_obj;
1172
1173 unsigned int cpp;
1174 int back_offset;
1175@@ -104,7 +114,6 @@ typedef struct drm_i915_private {
1176
1177 wait_queue_head_t irq_queue;
1178 atomic_t irq_received;
1179- atomic_t irq_emitted;
1180 /** Protects user_irq_refcount and irq_mask_reg */
1181 spinlock_t user_irq_lock;
1182 /** Refcount for i915_user_irq_get() versus i915_user_irq_put(). */
1183@@ -210,8 +219,174 @@ typedef struct drm_i915_private {
1184 u8 saveDACMASK;
1185 u8 saveDACDATA[256*3]; /* 256 3-byte colors */
1186 u8 saveCR[37];
1187+
1188+ struct {
1189+ struct drm_mm gtt_space;
1190+
1191+ /**
1192+ * List of objects currently involved in rendering from the
1193+ * ringbuffer.
1194+ *
1195+ * A reference is held on the buffer while on this list.
1196+ */
1197+ struct list_head active_list;
1198+
1199+ /**
1200+ * List of objects which are not in the ringbuffer but which
1201+ * still have a write_domain which needs to be flushed before
1202+ * unbinding.
1203+ *
1204+ * A reference is held on the buffer while on this list.
1205+ */
1206+ struct list_head flushing_list;
1207+
1208+ /**
1209+ * LRU list of objects which are not in the ringbuffer and
1210+ * are ready to unbind, but are still in the GTT.
1211+ *
1212+ * A reference is not held on the buffer while on this list,
1213+ * as merely being GTT-bound shouldn't prevent its being
1214+ * freed, and we'll pull it off the list in the free path.
1215+ */
1216+ struct list_head inactive_list;
1217+
1218+ /**
1219+ * List of breadcrumbs associated with GPU requests currently
1220+ * outstanding.
1221+ */
1222+ struct list_head request_list;
1223+
1224+ /**
1225+ * We leave the user IRQ off as much as possible,
1226+ * but this means that requests will finish and never
1227+ * be retired once the system goes idle. Set a timer to
1228+ * fire periodically while the ring is running. When it
1229+ * fires, go retire requests.
1230+ */
1231+ struct delayed_work retire_work;
1232+
1233+ uint32_t next_gem_seqno;
1234+
1235+ /**
1236+ * Waiting sequence number, if any
1237+ */
1238+ uint32_t waiting_gem_seqno;
1239+
1240+ /**
1241+ * Last seq seen at irq time
1242+ */
1243+ uint32_t irq_gem_seqno;
1244+
1245+ /**
1246+ * Flag if the X Server, and thus DRM, is not currently in
1247+ * control of the device.
1248+ *
1249+ * This is set between LeaveVT and EnterVT. It needs to be
1250+ * replaced with a semaphore. It also needs to be
1251+ * transitioned away from for kernel modesetting.
1252+ */
1253+ int suspended;
1254+
1255+ /**
1256+ * Flag if the hardware appears to be wedged.
1257+ *
1258+ * This is set when attempts to idle the device timeout.
1259+ * It prevents command submission from occuring and makes
1260+ * every pending request fail
1261+ */
1262+ int wedged;
1263+
1264+ /** Bit 6 swizzling required for X tiling */
1265+ uint32_t bit_6_swizzle_x;
1266+ /** Bit 6 swizzling required for Y tiling */
1267+ uint32_t bit_6_swizzle_y;
1268+ } mm;
1269 } drm_i915_private_t;
1270
1271+/** driver private structure attached to each drm_gem_object */
1272+struct drm_i915_gem_object {
1273+ struct drm_gem_object *obj;
1274+
1275+ /** Current space allocated to this object in the GTT, if any. */
1276+ struct drm_mm_node *gtt_space;
1277+
1278+ /** This object's place on the active/flushing/inactive lists */
1279+ struct list_head list;
1280+
1281+ /**
1282+ * This is set if the object is on the active or flushing lists
1283+ * (has pending rendering), and is not set if it's on inactive (ready
1284+ * to be unbound).
1285+ */
1286+ int active;
1287+
1288+ /**
1289+ * This is set if the object has been written to since last bound
1290+ * to the GTT
1291+ */
1292+ int dirty;
1293+
1294+ /** AGP memory structure for our GTT binding. */
1295+ DRM_AGP_MEM *agp_mem;
1296+
1297+ struct page **page_list;
1298+
1299+ /**
1300+ * Current offset of the object in GTT space.
1301+ *
1302+ * This is the same as gtt_space->start
1303+ */
1304+ uint32_t gtt_offset;
1305+
1306+ /** Boolean whether this object has a valid gtt offset. */
1307+ int gtt_bound;
1308+
1309+ /** How many users have pinned this object in GTT space */
1310+ int pin_count;
1311+
1312+ /** Breadcrumb of last rendering to the buffer. */
1313+ uint32_t last_rendering_seqno;
1314+
1315+ /** Current tiling mode for the object. */
1316+ uint32_t tiling_mode;
1317+
1318+ /**
1319+ * Flagging of which individual pages are valid in GEM_DOMAIN_CPU when
1320+ * GEM_DOMAIN_CPU is not in the object's read domain.
1321+ */
1322+ uint8_t *page_cpu_valid;
1323+};
1324+
1325+/**
1326+ * Request queue structure.
1327+ *
1328+ * The request queue allows us to note sequence numbers that have been emitted
1329+ * and may be associated with active buffers to be retired.
1330+ *
1331+ * By keeping this list, we can avoid having to do questionable
1332+ * sequence-number comparisons on buffer last_rendering_seqnos, and associate
1333+ * an emission time with seqnos for tracking how far ahead of the GPU we are.
1334+ */
1335+struct drm_i915_gem_request {
1336+ /** GEM sequence number associated with this request. */
1337+ uint32_t seqno;
1338+
1339+ /** Time at which this request was emitted, in jiffies. */
1340+ unsigned long emitted_jiffies;
1341+
1342+ /** Cache domains that were flushed at the start of the request. */
1343+ uint32_t flush_domains;
1344+
1345+ struct list_head list;
1346+};
1347+
1348+struct drm_i915_file_private {
1349+ struct {
1350+ uint32_t last_gem_seqno;
1351+ uint32_t last_gem_throttle_seqno;
1352+ } mm;
1353+};
1354+
1355 extern struct drm_ioctl_desc i915_ioctls[];
1356 extern int i915_max_ioctl;
1357
1358@@ -219,18 +394,26 @@ extern int i915_max_ioctl;
1359 extern void i915_kernel_lost_context(struct drm_device * dev);
1360 extern int i915_driver_load(struct drm_device *, unsigned long flags);
1361 extern int i915_driver_unload(struct drm_device *);
1362+extern int i915_driver_open(struct drm_device *dev, struct drm_file *file_priv);
1363 extern void i915_driver_lastclose(struct drm_device * dev);
1364 extern void i915_driver_preclose(struct drm_device *dev,
1365 struct drm_file *file_priv);
1366+extern void i915_driver_postclose(struct drm_device *dev,
1367+ struct drm_file *file_priv);
1368 extern int i915_driver_device_is_agp(struct drm_device * dev);
1369 extern long i915_compat_ioctl(struct file *filp, unsigned int cmd,
1370 unsigned long arg);
1371+extern int i915_emit_box(struct drm_device *dev,
1372+ struct drm_clip_rect __user *boxes,
1373+ int i, int DR1, int DR4);
1374
1375 /* i915_irq.c */
1376 extern int i915_irq_emit(struct drm_device *dev, void *data,
1377 struct drm_file *file_priv);
1378 extern int i915_irq_wait(struct drm_device *dev, void *data,
1379 struct drm_file *file_priv);
1380+void i915_user_irq_get(struct drm_device *dev);
1381+void i915_user_irq_put(struct drm_device *dev);
1382
1383 extern int i915_driver_vblank_wait(struct drm_device *dev, unsigned int *sequence);
1384 extern int i915_driver_vblank_wait2(struct drm_device *dev, unsigned int *sequence);
1385@@ -257,6 +440,67 @@ extern int i915_mem_destroy_heap(struct
1386 extern void i915_mem_takedown(struct mem_block **heap);
1387 extern void i915_mem_release(struct drm_device * dev,
1388 struct drm_file *file_priv, struct mem_block *heap);
1389+/* i915_gem.c */
1390+int i915_gem_init_ioctl(struct drm_device *dev, void *data,
1391+ struct drm_file *file_priv);
1392+int i915_gem_create_ioctl(struct drm_device *dev, void *data,
1393+ struct drm_file *file_priv);
1394+int i915_gem_pread_ioctl(struct drm_device *dev, void *data,
1395+ struct drm_file *file_priv);
1396+int i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
1397+ struct drm_file *file_priv);
1398+int i915_gem_mmap_ioctl(struct drm_device *dev, void *data,
1399+ struct drm_file *file_priv);
1400+int i915_gem_set_domain_ioctl(struct drm_device *dev, void *data,
1401+ struct drm_file *file_priv);
1402+int i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data,
1403+ struct drm_file *file_priv);
1404+int i915_gem_execbuffer(struct drm_device *dev, void *data,
1405+ struct drm_file *file_priv);
1406+int i915_gem_pin_ioctl(struct drm_device *dev, void *data,
1407+ struct drm_file *file_priv);
1408+int i915_gem_unpin_ioctl(struct drm_device *dev, void *data,
1409+ struct drm_file *file_priv);
1410+int i915_gem_busy_ioctl(struct drm_device *dev, void *data,
1411+ struct drm_file *file_priv);
1412+int i915_gem_throttle_ioctl(struct drm_device *dev, void *data,
1413+ struct drm_file *file_priv);
1414+int i915_gem_entervt_ioctl(struct drm_device *dev, void *data,
1415+ struct drm_file *file_priv);
1416+int i915_gem_leavevt_ioctl(struct drm_device *dev, void *data,
1417+ struct drm_file *file_priv);
1418+int i915_gem_set_tiling(struct drm_device *dev, void *data,
1419+ struct drm_file *file_priv);
1420+int i915_gem_get_tiling(struct drm_device *dev, void *data,
1421+ struct drm_file *file_priv);
1422+void i915_gem_load(struct drm_device *dev);
1423+int i915_gem_proc_init(struct drm_minor *minor);
1424+void i915_gem_proc_cleanup(struct drm_minor *minor);
1425+int i915_gem_init_object(struct drm_gem_object *obj);
1426+void i915_gem_free_object(struct drm_gem_object *obj);
1427+int i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment);
1428+void i915_gem_object_unpin(struct drm_gem_object *obj);
1429+void i915_gem_lastclose(struct drm_device *dev);
1430+uint32_t i915_get_gem_seqno(struct drm_device *dev);
1431+void i915_gem_retire_requests(struct drm_device *dev);
1432+void i915_gem_retire_work_handler(struct work_struct *work);
1433+void i915_gem_clflush_object(struct drm_gem_object *obj);
1434+
1435+/* i915_gem_tiling.c */
1436+void i915_gem_detect_bit_6_swizzle(struct drm_device *dev);
1437+
1438+/* i915_gem_debug.c */
1439+void i915_gem_dump_object(struct drm_gem_object *obj, int len,
1440+ const char *where, uint32_t mark);
1441+#if WATCH_INACTIVE
1442+void i915_verify_inactive(struct drm_device *dev, char *file, int line);
1443+#else
1444+#define i915_verify_inactive(dev, file, line)
1445+#endif
1446+void i915_gem_object_check_coherency(struct drm_gem_object *obj, int handle);
1447+void i915_gem_dump_object(struct drm_gem_object *obj, int len,
1448+ const char *where, uint32_t mark);
1449+void i915_dump_lru(struct drm_device *dev, const char *where);
1450
1451 #define I915_READ(reg) DRM_READ32(dev_priv->mmio_map, (reg))
1452 #define I915_WRITE(reg,val) DRM_WRITE32(dev_priv->mmio_map, (reg), (val))
1453@@ -309,6 +553,7 @@ extern void i915_mem_release(struct drm_
1454 */
1455 #define READ_HWSP(dev_priv, reg) (((volatile u32*)(dev_priv->hw_status_page))[reg])
1456 #define READ_BREADCRUMB(dev_priv) READ_HWSP(dev_priv, 5)
1457+#define I915_GEM_HWS_INDEX 0x10
1458
1459 extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
1460
1461--- /dev/null
1462+++ b/drivers/gpu/drm/i915/i915_gem.c
1463@@ -0,0 +1,2508 @@
1464+/*
1465+ * Copyright © 2008 Intel Corporation
1466+ *
1467+ * Permission is hereby granted, free of charge, to any person obtaining a
1468+ * copy of this software and associated documentation files (the "Software"),
1469+ * to deal in the Software without restriction, including without limitation
1470+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
1471+ * and/or sell copies of the Software, and to permit persons to whom the
1472+ * Software is furnished to do so, subject to the following conditions:
1473+ *
1474+ * The above copyright notice and this permission notice (including the next
1475+ * paragraph) shall be included in all copies or substantial portions of the
1476+ * Software.
1477+ *
1478+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1479+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1480+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
1481+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1482+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
1483+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
1484+ * IN THE SOFTWARE.
1485+ *
1486+ * Authors:
1487+ * Eric Anholt <eric@anholt.net>
1488+ *
1489+ */
1490+
1491+#include "drmP.h"
1492+#include "drm.h"
1493+#include "i915_drm.h"
1494+#include "i915_drv.h"
1495+#include <linux/swap.h>
1496+
1497+static int
1498+i915_gem_object_set_domain(struct drm_gem_object *obj,
1499+ uint32_t read_domains,
1500+ uint32_t write_domain);
1501+static int
1502+i915_gem_object_set_domain_range(struct drm_gem_object *obj,
1503+ uint64_t offset,
1504+ uint64_t size,
1505+ uint32_t read_domains,
1506+ uint32_t write_domain);
1507+static int
1508+i915_gem_set_domain(struct drm_gem_object *obj,
1509+ struct drm_file *file_priv,
1510+ uint32_t read_domains,
1511+ uint32_t write_domain);
1512+static int i915_gem_object_get_page_list(struct drm_gem_object *obj);
1513+static void i915_gem_object_free_page_list(struct drm_gem_object *obj);
1514+static int i915_gem_object_wait_rendering(struct drm_gem_object *obj);
1515+
1516+int
1517+i915_gem_init_ioctl(struct drm_device *dev, void *data,
1518+ struct drm_file *file_priv)
1519+{
1520+ drm_i915_private_t *dev_priv = dev->dev_private;
1521+ struct drm_i915_gem_init *args = data;
1522+
1523+ mutex_lock(&dev->struct_mutex);
1524+
1525+ if (args->gtt_start >= args->gtt_end ||
1526+ (args->gtt_start & (PAGE_SIZE - 1)) != 0 ||
1527+ (args->gtt_end & (PAGE_SIZE - 1)) != 0) {
1528+ mutex_unlock(&dev->struct_mutex);
1529+ return -EINVAL;
1530+ }
1531+
1532+ drm_mm_init(&dev_priv->mm.gtt_space, args->gtt_start,
1533+ args->gtt_end - args->gtt_start);
1534+
1535+ dev->gtt_total = (uint32_t) (args->gtt_end - args->gtt_start);
1536+
1537+ mutex_unlock(&dev->struct_mutex);
1538+
1539+ return 0;
1540+}
1541+
1542+
1543+/**
1544+ * Creates a new mm object and returns a handle to it.
1545+ */
1546+int
1547+i915_gem_create_ioctl(struct drm_device *dev, void *data,
1548+ struct drm_file *file_priv)
1549+{
1550+ struct drm_i915_gem_create *args = data;
1551+ struct drm_gem_object *obj;
1552+ int handle, ret;
1553+
1554+ args->size = roundup(args->size, PAGE_SIZE);
1555+
1556+ /* Allocate the new object */
1557+ obj = drm_gem_object_alloc(dev, args->size);
1558+ if (obj == NULL)
1559+ return -ENOMEM;
1560+
1561+ ret = drm_gem_handle_create(file_priv, obj, &handle);
1562+ mutex_lock(&dev->struct_mutex);
1563+ drm_gem_object_handle_unreference(obj);
1564+ mutex_unlock(&dev->struct_mutex);
1565+
1566+ if (ret)
1567+ return ret;
1568+
1569+ args->handle = handle;
1570+
1571+ return 0;
1572+}
1573+
1574+/**
1575+ * Reads data from the object referenced by handle.
1576+ *
1577+ * On error, the contents of *data are undefined.
1578+ */
1579+int
1580+i915_gem_pread_ioctl(struct drm_device *dev, void *data,
1581+ struct drm_file *file_priv)
1582+{
1583+ struct drm_i915_gem_pread *args = data;
1584+ struct drm_gem_object *obj;
1585+ struct drm_i915_gem_object *obj_priv;
1586+ ssize_t read;
1587+ loff_t offset;
1588+ int ret;
1589+
1590+ obj = drm_gem_object_lookup(dev, file_priv, args->handle);
1591+ if (obj == NULL)
1592+ return -EBADF;
1593+ obj_priv = obj->driver_private;
1594+
1595+ /* Bounds check source.
1596+ *
1597+ * XXX: This could use review for overflow issues...
1598+ */
1599+ if (args->offset > obj->size || args->size > obj->size ||
1600+ args->offset + args->size > obj->size) {
1601+ drm_gem_object_unreference(obj);
1602+ return -EINVAL;
1603+ }
1604+
1605+ mutex_lock(&dev->struct_mutex);
1606+
1607+ ret = i915_gem_object_set_domain_range(obj, args->offset, args->size,
1608+ I915_GEM_DOMAIN_CPU, 0);
1609+ if (ret != 0) {
1610+ drm_gem_object_unreference(obj);
1611+ mutex_unlock(&dev->struct_mutex);
1612+ }
1613+
1614+ offset = args->offset;
1615+
1616+ read = vfs_read(obj->filp, (char __user *)(uintptr_t)args->data_ptr,
1617+ args->size, &offset);
1618+ if (read != args->size) {
1619+ drm_gem_object_unreference(obj);
1620+ mutex_unlock(&dev->struct_mutex);
1621+ if (read < 0)
1622+ return read;
1623+ else
1624+ return -EINVAL;
1625+ }
1626+
1627+ drm_gem_object_unreference(obj);
1628+ mutex_unlock(&dev->struct_mutex);
1629+
1630+ return 0;
1631+}
1632+
1633+static int
1634+i915_gem_gtt_pwrite(struct drm_device *dev, struct drm_gem_object *obj,
1635+ struct drm_i915_gem_pwrite *args,
1636+ struct drm_file *file_priv)
1637+{
1638+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
1639+ ssize_t remain;
1640+ loff_t offset;
1641+ char __user *user_data;
1642+ char *vaddr;
1643+ int i, o, l;
1644+ int ret = 0;
1645+ unsigned long pfn;
1646+ unsigned long unwritten;
1647+
1648+ user_data = (char __user *) (uintptr_t) args->data_ptr;
1649+ remain = args->size;
1650+ if (!access_ok(VERIFY_READ, user_data, remain))
1651+ return -EFAULT;
1652+
1653+
1654+ mutex_lock(&dev->struct_mutex);
1655+ ret = i915_gem_object_pin(obj, 0);
1656+ if (ret) {
1657+ mutex_unlock(&dev->struct_mutex);
1658+ return ret;
1659+ }
1660+ ret = i915_gem_set_domain(obj, file_priv,
1661+ I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
1662+ if (ret)
1663+ goto fail;
1664+
1665+ obj_priv = obj->driver_private;
1666+ offset = obj_priv->gtt_offset + args->offset;
1667+ obj_priv->dirty = 1;
1668+
1669+ while (remain > 0) {
1670+ /* Operation in this page
1671+ *
1672+ * i = page number
1673+ * o = offset within page
1674+ * l = bytes to copy
1675+ */
1676+ i = offset >> PAGE_SHIFT;
1677+ o = offset & (PAGE_SIZE-1);
1678+ l = remain;
1679+ if ((o + l) > PAGE_SIZE)
1680+ l = PAGE_SIZE - o;
1681+
1682+ pfn = (dev->agp->base >> PAGE_SHIFT) + i;
1683+
1684+#ifdef DRM_KMAP_ATOMIC_PROT_PFN
1685+ /* kmap_atomic can't map IO pages on non-HIGHMEM kernels
1686+ */
1687+ vaddr = kmap_atomic_prot_pfn(pfn, KM_USER0,
1688+ __pgprot(__PAGE_KERNEL));
1689+#if WATCH_PWRITE
1690+ DRM_INFO("pwrite i %d o %d l %d pfn %ld vaddr %p\n",
1691+ i, o, l, pfn, vaddr);
1692+#endif
1693+ unwritten = __copy_from_user_inatomic_nocache(vaddr + o,
1694+ user_data, l);
1695+ kunmap_atomic(vaddr, KM_USER0);
1696+
1697+ if (unwritten)
1698+#endif
1699+ {
1700+ vaddr = ioremap(pfn << PAGE_SHIFT, PAGE_SIZE);
1701+#if WATCH_PWRITE
1702+ DRM_INFO("pwrite slow i %d o %d l %d "
1703+ "pfn %ld vaddr %p\n",
1704+ i, o, l, pfn, vaddr);
1705+#endif
1706+ if (vaddr == NULL) {
1707+ ret = -EFAULT;
1708+ goto fail;
1709+ }
1710+ unwritten = __copy_from_user(vaddr + o, user_data, l);
1711+#if WATCH_PWRITE
1712+ DRM_INFO("unwritten %ld\n", unwritten);
1713+#endif
1714+ iounmap(vaddr);
1715+ if (unwritten) {
1716+ ret = -EFAULT;
1717+ goto fail;
1718+ }
1719+ }
1720+
1721+ remain -= l;
1722+ user_data += l;
1723+ offset += l;
1724+ }
1725+#if WATCH_PWRITE && 1
1726+ i915_gem_clflush_object(obj);
1727+ i915_gem_dump_object(obj, args->offset + args->size, __func__, ~0);
1728+ i915_gem_clflush_object(obj);
1729+#endif
1730+
1731+fail:
1732+ i915_gem_object_unpin(obj);
1733+ mutex_unlock(&dev->struct_mutex);
1734+
1735+ return ret;
1736+}
1737+
1738+int
1739+i915_gem_shmem_pwrite(struct drm_device *dev, struct drm_gem_object *obj,
1740+ struct drm_i915_gem_pwrite *args,
1741+ struct drm_file *file_priv)
1742+{
1743+ int ret;
1744+ loff_t offset;
1745+ ssize_t written;
1746+
1747+ mutex_lock(&dev->struct_mutex);
1748+
1749+ ret = i915_gem_set_domain(obj, file_priv,
1750+ I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
1751+ if (ret) {
1752+ mutex_unlock(&dev->struct_mutex);
1753+ return ret;
1754+ }
1755+
1756+ offset = args->offset;
1757+
1758+ written = vfs_write(obj->filp,
1759+ (char __user *)(uintptr_t) args->data_ptr,
1760+ args->size, &offset);
1761+ if (written != args->size) {
1762+ mutex_unlock(&dev->struct_mutex);
1763+ if (written < 0)
1764+ return written;
1765+ else
1766+ return -EINVAL;
1767+ }
1768+
1769+ mutex_unlock(&dev->struct_mutex);
1770+
1771+ return 0;
1772+}
1773+
1774+/**
1775+ * Writes data to the object referenced by handle.
1776+ *
1777+ * On error, the contents of the buffer that were to be modified are undefined.
1778+ */
1779+int
1780+i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
1781+ struct drm_file *file_priv)
1782+{
1783+ struct drm_i915_gem_pwrite *args = data;
1784+ struct drm_gem_object *obj;
1785+ struct drm_i915_gem_object *obj_priv;
1786+ int ret = 0;
1787+
1788+ obj = drm_gem_object_lookup(dev, file_priv, args->handle);
1789+ if (obj == NULL)
1790+ return -EBADF;
1791+ obj_priv = obj->driver_private;
1792+
1793+ /* Bounds check destination.
1794+ *
1795+ * XXX: This could use review for overflow issues...
1796+ */
1797+ if (args->offset > obj->size || args->size > obj->size ||
1798+ args->offset + args->size > obj->size) {
1799+ drm_gem_object_unreference(obj);
1800+ return -EINVAL;
1801+ }
1802+
1803+ /* We can only do the GTT pwrite on untiled buffers, as otherwise
1804+ * it would end up going through the fenced access, and we'll get
1805+ * different detiling behavior between reading and writing.
1806+ * pread/pwrite currently are reading and writing from the CPU
1807+ * perspective, requiring manual detiling by the client.
1808+ */
1809+ if (obj_priv->tiling_mode == I915_TILING_NONE &&
1810+ dev->gtt_total != 0)
1811+ ret = i915_gem_gtt_pwrite(dev, obj, args, file_priv);
1812+ else
1813+ ret = i915_gem_shmem_pwrite(dev, obj, args, file_priv);
1814+
1815+#if WATCH_PWRITE
1816+ if (ret)
1817+ DRM_INFO("pwrite failed %d\n", ret);
1818+#endif
1819+
1820+ drm_gem_object_unreference(obj);
1821+
1822+ return ret;
1823+}
1824+
1825+/**
1826+ * Called when user space prepares to use an object
1827+ */
1828+int
1829+i915_gem_set_domain_ioctl(struct drm_device *dev, void *data,
1830+ struct drm_file *file_priv)
1831+{
1832+ struct drm_i915_gem_set_domain *args = data;
1833+ struct drm_gem_object *obj;
1834+ int ret;
1835+
1836+ if (!(dev->driver->driver_features & DRIVER_GEM))
1837+ return -ENODEV;
1838+
1839+ obj = drm_gem_object_lookup(dev, file_priv, args->handle);
1840+ if (obj == NULL)
1841+ return -EBADF;
1842+
1843+ mutex_lock(&dev->struct_mutex);
1844+#if WATCH_BUF
1845+ DRM_INFO("set_domain_ioctl %p(%d), %08x %08x\n",
1846+ obj, obj->size, args->read_domains, args->write_domain);
1847+#endif
1848+ ret = i915_gem_set_domain(obj, file_priv,
1849+ args->read_domains, args->write_domain);
1850+ drm_gem_object_unreference(obj);
1851+ mutex_unlock(&dev->struct_mutex);
1852+ return ret;
1853+}
1854+
1855+/**
1856+ * Called when user space has done writes to this buffer
1857+ */
1858+int
1859+i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data,
1860+ struct drm_file *file_priv)
1861+{
1862+ struct drm_i915_gem_sw_finish *args = data;
1863+ struct drm_gem_object *obj;
1864+ struct drm_i915_gem_object *obj_priv;
1865+ int ret = 0;
1866+
1867+ if (!(dev->driver->driver_features & DRIVER_GEM))
1868+ return -ENODEV;
1869+
1870+ mutex_lock(&dev->struct_mutex);
1871+ obj = drm_gem_object_lookup(dev, file_priv, args->handle);
1872+ if (obj == NULL) {
1873+ mutex_unlock(&dev->struct_mutex);
1874+ return -EBADF;
1875+ }
1876+
1877+#if WATCH_BUF
1878+ DRM_INFO("%s: sw_finish %d (%p %d)\n",
1879+ __func__, args->handle, obj, obj->size);
1880+#endif
1881+ obj_priv = obj->driver_private;
1882+
1883+ /* Pinned buffers may be scanout, so flush the cache */
1884+ if ((obj->write_domain & I915_GEM_DOMAIN_CPU) && obj_priv->pin_count) {
1885+ i915_gem_clflush_object(obj);
1886+ drm_agp_chipset_flush(dev);
1887+ }
1888+ drm_gem_object_unreference(obj);
1889+ mutex_unlock(&dev->struct_mutex);
1890+ return ret;
1891+}
1892+
1893+/**
1894+ * Maps the contents of an object, returning the address it is mapped
1895+ * into.
1896+ *
1897+ * While the mapping holds a reference on the contents of the object, it doesn't
1898+ * imply a ref on the object itself.
1899+ */
1900+int
1901+i915_gem_mmap_ioctl(struct drm_device *dev, void *data,
1902+ struct drm_file *file_priv)
1903+{
1904+ struct drm_i915_gem_mmap *args = data;
1905+ struct drm_gem_object *obj;
1906+ loff_t offset;
1907+ unsigned long addr;
1908+
1909+ if (!(dev->driver->driver_features & DRIVER_GEM))
1910+ return -ENODEV;
1911+
1912+ obj = drm_gem_object_lookup(dev, file_priv, args->handle);
1913+ if (obj == NULL)
1914+ return -EBADF;
1915+
1916+ offset = args->offset;
1917+
1918+ down_write(&current->mm->mmap_sem);
1919+ addr = do_mmap(obj->filp, 0, args->size,
1920+ PROT_READ | PROT_WRITE, MAP_SHARED,
1921+ args->offset);
1922+ up_write(&current->mm->mmap_sem);
1923+ mutex_lock(&dev->struct_mutex);
1924+ drm_gem_object_unreference(obj);
1925+ mutex_unlock(&dev->struct_mutex);
1926+ if (IS_ERR((void *)addr))
1927+ return addr;
1928+
1929+ args->addr_ptr = (uint64_t) addr;
1930+
1931+ return 0;
1932+}
1933+
1934+static void
1935+i915_gem_object_free_page_list(struct drm_gem_object *obj)
1936+{
1937+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
1938+ int page_count = obj->size / PAGE_SIZE;
1939+ int i;
1940+
1941+ if (obj_priv->page_list == NULL)
1942+ return;
1943+
1944+
1945+ for (i = 0; i < page_count; i++)
1946+ if (obj_priv->page_list[i] != NULL) {
1947+ if (obj_priv->dirty)
1948+ set_page_dirty(obj_priv->page_list[i]);
1949+ mark_page_accessed(obj_priv->page_list[i]);
1950+ page_cache_release(obj_priv->page_list[i]);
1951+ }
1952+ obj_priv->dirty = 0;
1953+
1954+ drm_free(obj_priv->page_list,
1955+ page_count * sizeof(struct page *),
1956+ DRM_MEM_DRIVER);
1957+ obj_priv->page_list = NULL;
1958+}
1959+
1960+static void
1961+i915_gem_object_move_to_active(struct drm_gem_object *obj)
1962+{
1963+ struct drm_device *dev = obj->dev;
1964+ drm_i915_private_t *dev_priv = dev->dev_private;
1965+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
1966+
1967+ /* Add a reference if we're newly entering the active list. */
1968+ if (!obj_priv->active) {
1969+ drm_gem_object_reference(obj);
1970+ obj_priv->active = 1;
1971+ }
1972+ /* Move from whatever list we were on to the tail of execution. */
1973+ list_move_tail(&obj_priv->list,
1974+ &dev_priv->mm.active_list);
1975+}
1976+
1977+
1978+static void
1979+i915_gem_object_move_to_inactive(struct drm_gem_object *obj)
1980+{
1981+ struct drm_device *dev = obj->dev;
1982+ drm_i915_private_t *dev_priv = dev->dev_private;
1983+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
1984+
1985+ i915_verify_inactive(dev, __FILE__, __LINE__);
1986+ if (obj_priv->pin_count != 0)
1987+ list_del_init(&obj_priv->list);
1988+ else
1989+ list_move_tail(&obj_priv->list, &dev_priv->mm.inactive_list);
1990+
1991+ if (obj_priv->active) {
1992+ obj_priv->active = 0;
1993+ drm_gem_object_unreference(obj);
1994+ }
1995+ i915_verify_inactive(dev, __FILE__, __LINE__);
1996+}
1997+
1998+/**
1999+ * Creates a new sequence number, emitting a write of it to the status page
2000+ * plus an interrupt, which will trigger i915_user_interrupt_handler.
2001+ *
2002+ * Must be called with struct_lock held.
2003+ *
2004+ * Returned sequence numbers are nonzero on success.
2005+ */
2006+static uint32_t
2007+i915_add_request(struct drm_device *dev, uint32_t flush_domains)
2008+{
2009+ drm_i915_private_t *dev_priv = dev->dev_private;
2010+ struct drm_i915_gem_request *request;
2011+ uint32_t seqno;
2012+ int was_empty;
2013+ RING_LOCALS;
2014+
2015+ request = drm_calloc(1, sizeof(*request), DRM_MEM_DRIVER);
2016+ if (request == NULL)
2017+ return 0;
2018+
2019+ /* Grab the seqno we're going to make this request be, and bump the
2020+ * next (skipping 0 so it can be the reserved no-seqno value).
2021+ */
2022+ seqno = dev_priv->mm.next_gem_seqno;
2023+ dev_priv->mm.next_gem_seqno++;
2024+ if (dev_priv->mm.next_gem_seqno == 0)
2025+ dev_priv->mm.next_gem_seqno++;
2026+
2027+ BEGIN_LP_RING(4);
2028+ OUT_RING(MI_STORE_DWORD_INDEX);
2029+ OUT_RING(I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
2030+ OUT_RING(seqno);
2031+
2032+ OUT_RING(MI_USER_INTERRUPT);
2033+ ADVANCE_LP_RING();
2034+
2035+ DRM_DEBUG("%d\n", seqno);
2036+
2037+ request->seqno = seqno;
2038+ request->emitted_jiffies = jiffies;
2039+ request->flush_domains = flush_domains;
2040+ was_empty = list_empty(&dev_priv->mm.request_list);
2041+ list_add_tail(&request->list, &dev_priv->mm.request_list);
2042+
2043+ if (was_empty)
2044+ schedule_delayed_work(&dev_priv->mm.retire_work, HZ);
2045+ return seqno;
2046+}
2047+
2048+/**
2049+ * Command execution barrier
2050+ *
2051+ * Ensures that all commands in the ring are finished
2052+ * before signalling the CPU
2053+ */
2054+uint32_t
2055+i915_retire_commands(struct drm_device *dev)
2056+{
2057+ drm_i915_private_t *dev_priv = dev->dev_private;
2058+ uint32_t cmd = MI_FLUSH | MI_NO_WRITE_FLUSH;
2059+ uint32_t flush_domains = 0;
2060+ RING_LOCALS;
2061+
2062+ /* The sampler always gets flushed on i965 (sigh) */
2063+ if (IS_I965G(dev))
2064+ flush_domains |= I915_GEM_DOMAIN_SAMPLER;
2065+ BEGIN_LP_RING(2);
2066+ OUT_RING(cmd);
2067+ OUT_RING(0); /* noop */
2068+ ADVANCE_LP_RING();
2069+ return flush_domains;
2070+}
2071+
2072+/**
2073+ * Moves buffers associated only with the given active seqno from the active
2074+ * to inactive list, potentially freeing them.
2075+ */
2076+static void
2077+i915_gem_retire_request(struct drm_device *dev,
2078+ struct drm_i915_gem_request *request)
2079+{
2080+ drm_i915_private_t *dev_priv = dev->dev_private;
2081+
2082+ /* Move any buffers on the active list that are no longer referenced
2083+ * by the ringbuffer to the flushing/inactive lists as appropriate.
2084+ */
2085+ while (!list_empty(&dev_priv->mm.active_list)) {
2086+ struct drm_gem_object *obj;
2087+ struct drm_i915_gem_object *obj_priv;
2088+
2089+ obj_priv = list_first_entry(&dev_priv->mm.active_list,
2090+ struct drm_i915_gem_object,
2091+ list);
2092+ obj = obj_priv->obj;
2093+
2094+ /* If the seqno being retired doesn't match the oldest in the
2095+ * list, then the oldest in the list must still be newer than
2096+ * this seqno.
2097+ */
2098+ if (obj_priv->last_rendering_seqno != request->seqno)
2099+ return;
2100+#if WATCH_LRU
2101+ DRM_INFO("%s: retire %d moves to inactive list %p\n",
2102+ __func__, request->seqno, obj);
2103+#endif
2104+
2105+ if (obj->write_domain != 0) {
2106+ list_move_tail(&obj_priv->list,
2107+ &dev_priv->mm.flushing_list);
2108+ } else {
2109+ i915_gem_object_move_to_inactive(obj);
2110+ }
2111+ }
2112+
2113+ if (request->flush_domains != 0) {
2114+ struct drm_i915_gem_object *obj_priv, *next;
2115+
2116+ /* Clear the write domain and activity from any buffers
2117+ * that are just waiting for a flush matching the one retired.
2118+ */
2119+ list_for_each_entry_safe(obj_priv, next,
2120+ &dev_priv->mm.flushing_list, list) {
2121+ struct drm_gem_object *obj = obj_priv->obj;
2122+
2123+ if (obj->write_domain & request->flush_domains) {
2124+ obj->write_domain = 0;
2125+ i915_gem_object_move_to_inactive(obj);
2126+ }
2127+ }
2128+
2129+ }
2130+}
2131+
2132+/**
2133+ * Returns true if seq1 is later than seq2.
2134+ */
2135+static int
2136+i915_seqno_passed(uint32_t seq1, uint32_t seq2)
2137+{
2138+ return (int32_t)(seq1 - seq2) >= 0;
2139+}
2140+
2141+uint32_t
2142+i915_get_gem_seqno(struct drm_device *dev)
2143+{
2144+ drm_i915_private_t *dev_priv = dev->dev_private;
2145+
2146+ return READ_HWSP(dev_priv, I915_GEM_HWS_INDEX);
2147+}
2148+
2149+/**
2150+ * This function clears the request list as sequence numbers are passed.
2151+ */
2152+void
2153+i915_gem_retire_requests(struct drm_device *dev)
2154+{
2155+ drm_i915_private_t *dev_priv = dev->dev_private;
2156+ uint32_t seqno;
2157+
2158+ seqno = i915_get_gem_seqno(dev);
2159+
2160+ while (!list_empty(&dev_priv->mm.request_list)) {
2161+ struct drm_i915_gem_request *request;
2162+ uint32_t retiring_seqno;
2163+
2164+ request = list_first_entry(&dev_priv->mm.request_list,
2165+ struct drm_i915_gem_request,
2166+ list);
2167+ retiring_seqno = request->seqno;
2168+
2169+ if (i915_seqno_passed(seqno, retiring_seqno) ||
2170+ dev_priv->mm.wedged) {
2171+ i915_gem_retire_request(dev, request);
2172+
2173+ list_del(&request->list);
2174+ drm_free(request, sizeof(*request), DRM_MEM_DRIVER);
2175+ } else
2176+ break;
2177+ }
2178+}
2179+
2180+void
2181+i915_gem_retire_work_handler(struct work_struct *work)
2182+{
2183+ drm_i915_private_t *dev_priv;
2184+ struct drm_device *dev;
2185+
2186+ dev_priv = container_of(work, drm_i915_private_t,
2187+ mm.retire_work.work);
2188+ dev = dev_priv->dev;
2189+
2190+ mutex_lock(&dev->struct_mutex);
2191+ i915_gem_retire_requests(dev);
2192+ if (!list_empty(&dev_priv->mm.request_list))
2193+ schedule_delayed_work(&dev_priv->mm.retire_work, HZ);
2194+ mutex_unlock(&dev->struct_mutex);
2195+}
2196+
2197+/**
2198+ * Waits for a sequence number to be signaled, and cleans up the
2199+ * request and object lists appropriately for that event.
2200+ */
2201+int
2202+i915_wait_request(struct drm_device *dev, uint32_t seqno)
2203+{
2204+ drm_i915_private_t *dev_priv = dev->dev_private;
2205+ int ret = 0;
2206+
2207+ BUG_ON(seqno == 0);
2208+
2209+ if (!i915_seqno_passed(i915_get_gem_seqno(dev), seqno)) {
2210+ dev_priv->mm.waiting_gem_seqno = seqno;
2211+ i915_user_irq_get(dev);
2212+ ret = wait_event_interruptible(dev_priv->irq_queue,
2213+ i915_seqno_passed(i915_get_gem_seqno(dev),
2214+ seqno) ||
2215+ dev_priv->mm.wedged);
2216+ i915_user_irq_put(dev);
2217+ dev_priv->mm.waiting_gem_seqno = 0;
2218+ }
2219+ if (dev_priv->mm.wedged)
2220+ ret = -EIO;
2221+
2222+ if (ret && ret != -ERESTARTSYS)
2223+ DRM_ERROR("%s returns %d (awaiting %d at %d)\n",
2224+ __func__, ret, seqno, i915_get_gem_seqno(dev));
2225+
2226+ /* Directly dispatch request retiring. While we have the work queue
2227+ * to handle this, the waiter on a request often wants an associated
2228+ * buffer to have made it to the inactive list, and we would need
2229+ * a separate wait queue to handle that.
2230+ */
2231+ if (ret == 0)
2232+ i915_gem_retire_requests(dev);
2233+
2234+ return ret;
2235+}
2236+
2237+static void
2238+i915_gem_flush(struct drm_device *dev,
2239+ uint32_t invalidate_domains,
2240+ uint32_t flush_domains)
2241+{
2242+ drm_i915_private_t *dev_priv = dev->dev_private;
2243+ uint32_t cmd;
2244+ RING_LOCALS;
2245+
2246+#if WATCH_EXEC
2247+ DRM_INFO("%s: invalidate %08x flush %08x\n", __func__,
2248+ invalidate_domains, flush_domains);
2249+#endif
2250+
2251+ if (flush_domains & I915_GEM_DOMAIN_CPU)
2252+ drm_agp_chipset_flush(dev);
2253+
2254+ if ((invalidate_domains | flush_domains) & ~(I915_GEM_DOMAIN_CPU |
2255+ I915_GEM_DOMAIN_GTT)) {
2256+ /*
2257+ * read/write caches:
2258+ *
2259+ * I915_GEM_DOMAIN_RENDER is always invalidated, but is
2260+ * only flushed if MI_NO_WRITE_FLUSH is unset. On 965, it is
2261+ * also flushed at 2d versus 3d pipeline switches.
2262+ *
2263+ * read-only caches:
2264+ *
2265+ * I915_GEM_DOMAIN_SAMPLER is flushed on pre-965 if
2266+ * MI_READ_FLUSH is set, and is always flushed on 965.
2267+ *
2268+ * I915_GEM_DOMAIN_COMMAND may not exist?
2269+ *
2270+ * I915_GEM_DOMAIN_INSTRUCTION, which exists on 965, is
2271+ * invalidated when MI_EXE_FLUSH is set.
2272+ *
2273+ * I915_GEM_DOMAIN_VERTEX, which exists on 965, is
2274+ * invalidated with every MI_FLUSH.
2275+ *
2276+ * TLBs:
2277+ *
2278+ * On 965, TLBs associated with I915_GEM_DOMAIN_COMMAND
2279+ * and I915_GEM_DOMAIN_CPU in are invalidated at PTE write and
2280+ * I915_GEM_DOMAIN_RENDER and I915_GEM_DOMAIN_SAMPLER
2281+ * are flushed at any MI_FLUSH.
2282+ */
2283+
2284+ cmd = MI_FLUSH | MI_NO_WRITE_FLUSH;
2285+ if ((invalidate_domains|flush_domains) &
2286+ I915_GEM_DOMAIN_RENDER)
2287+ cmd &= ~MI_NO_WRITE_FLUSH;
2288+ if (!IS_I965G(dev)) {
2289+ /*
2290+ * On the 965, the sampler cache always gets flushed
2291+ * and this bit is reserved.
2292+ */
2293+ if (invalidate_domains & I915_GEM_DOMAIN_SAMPLER)
2294+ cmd |= MI_READ_FLUSH;
2295+ }
2296+ if (invalidate_domains & I915_GEM_DOMAIN_INSTRUCTION)
2297+ cmd |= MI_EXE_FLUSH;
2298+
2299+#if WATCH_EXEC
2300+ DRM_INFO("%s: queue flush %08x to ring\n", __func__, cmd);
2301+#endif
2302+ BEGIN_LP_RING(2);
2303+ OUT_RING(cmd);
2304+ OUT_RING(0); /* noop */
2305+ ADVANCE_LP_RING();
2306+ }
2307+}
2308+
2309+/**
2310+ * Ensures that all rendering to the object has completed and the object is
2311+ * safe to unbind from the GTT or access from the CPU.
2312+ */
2313+static int
2314+i915_gem_object_wait_rendering(struct drm_gem_object *obj)
2315+{
2316+ struct drm_device *dev = obj->dev;
2317+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
2318+ int ret;
2319+
2320+ /* If there are writes queued to the buffer, flush and
2321+ * create a new seqno to wait for.
2322+ */
2323+ if (obj->write_domain & ~(I915_GEM_DOMAIN_CPU|I915_GEM_DOMAIN_GTT)) {
2324+ uint32_t write_domain = obj->write_domain;
2325+#if WATCH_BUF
2326+ DRM_INFO("%s: flushing object %p from write domain %08x\n",
2327+ __func__, obj, write_domain);
2328+#endif
2329+ i915_gem_flush(dev, 0, write_domain);
2330+
2331+ i915_gem_object_move_to_active(obj);
2332+ obj_priv->last_rendering_seqno = i915_add_request(dev,
2333+ write_domain);
2334+ BUG_ON(obj_priv->last_rendering_seqno == 0);
2335+#if WATCH_LRU
2336+ DRM_INFO("%s: flush moves to exec list %p\n", __func__, obj);
2337+#endif
2338+ }
2339+
2340+ /* If there is rendering queued on the buffer being evicted, wait for
2341+ * it.
2342+ */
2343+ if (obj_priv->active) {
2344+#if WATCH_BUF
2345+ DRM_INFO("%s: object %p wait for seqno %08x\n",
2346+ __func__, obj, obj_priv->last_rendering_seqno);
2347+#endif
2348+ ret = i915_wait_request(dev, obj_priv->last_rendering_seqno);
2349+ if (ret != 0)
2350+ return ret;
2351+ }
2352+
2353+ return 0;
2354+}
2355+
2356+/**
2357+ * Unbinds an object from the GTT aperture.
2358+ */
2359+static int
2360+i915_gem_object_unbind(struct drm_gem_object *obj)
2361+{
2362+ struct drm_device *dev = obj->dev;
2363+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
2364+ int ret = 0;
2365+
2366+#if WATCH_BUF
2367+ DRM_INFO("%s:%d %p\n", __func__, __LINE__, obj);
2368+ DRM_INFO("gtt_space %p\n", obj_priv->gtt_space);
2369+#endif
2370+ if (obj_priv->gtt_space == NULL)
2371+ return 0;
2372+
2373+ if (obj_priv->pin_count != 0) {
2374+ DRM_ERROR("Attempting to unbind pinned buffer\n");
2375+ return -EINVAL;
2376+ }
2377+
2378+ /* Wait for any rendering to complete
2379+ */
2380+ ret = i915_gem_object_wait_rendering(obj);
2381+ if (ret) {
2382+ DRM_ERROR("wait_rendering failed: %d\n", ret);
2383+ return ret;
2384+ }
2385+
2386+ /* Move the object to the CPU domain to ensure that
2387+ * any possible CPU writes while it's not in the GTT
2388+ * are flushed when we go to remap it. This will
2389+ * also ensure that all pending GPU writes are finished
2390+ * before we unbind.
2391+ */
2392+ ret = i915_gem_object_set_domain(obj, I915_GEM_DOMAIN_CPU,
2393+ I915_GEM_DOMAIN_CPU);
2394+ if (ret) {
2395+ DRM_ERROR("set_domain failed: %d\n", ret);
2396+ return ret;
2397+ }
2398+
2399+ if (obj_priv->agp_mem != NULL) {
2400+ drm_unbind_agp(obj_priv->agp_mem);
2401+ drm_free_agp(obj_priv->agp_mem, obj->size / PAGE_SIZE);
2402+ obj_priv->agp_mem = NULL;
2403+ }
2404+
2405+ BUG_ON(obj_priv->active);
2406+
2407+ i915_gem_object_free_page_list(obj);
2408+
2409+ if (obj_priv->gtt_space) {
2410+ atomic_dec(&dev->gtt_count);
2411+ atomic_sub(obj->size, &dev->gtt_memory);
2412+
2413+ drm_mm_put_block(obj_priv->gtt_space);
2414+ obj_priv->gtt_space = NULL;
2415+ }
2416+
2417+ /* Remove ourselves from the LRU list if present. */
2418+ if (!list_empty(&obj_priv->list))
2419+ list_del_init(&obj_priv->list);
2420+
2421+ return 0;
2422+}
2423+
2424+static int
2425+i915_gem_evict_something(struct drm_device *dev)
2426+{
2427+ drm_i915_private_t *dev_priv = dev->dev_private;
2428+ struct drm_gem_object *obj;
2429+ struct drm_i915_gem_object *obj_priv;
2430+ int ret = 0;
2431+
2432+ for (;;) {
2433+ /* If there's an inactive buffer available now, grab it
2434+ * and be done.
2435+ */
2436+ if (!list_empty(&dev_priv->mm.inactive_list)) {
2437+ obj_priv = list_first_entry(&dev_priv->mm.inactive_list,
2438+ struct drm_i915_gem_object,
2439+ list);
2440+ obj = obj_priv->obj;
2441+ BUG_ON(obj_priv->pin_count != 0);
2442+#if WATCH_LRU
2443+ DRM_INFO("%s: evicting %p\n", __func__, obj);
2444+#endif
2445+ BUG_ON(obj_priv->active);
2446+
2447+ /* Wait on the rendering and unbind the buffer. */
2448+ ret = i915_gem_object_unbind(obj);
2449+ break;
2450+ }
2451+
2452+ /* If we didn't get anything, but the ring is still processing
2453+ * things, wait for one of those things to finish and hopefully
2454+ * leave us a buffer to evict.
2455+ */
2456+ if (!list_empty(&dev_priv->mm.request_list)) {
2457+ struct drm_i915_gem_request *request;
2458+
2459+ request = list_first_entry(&dev_priv->mm.request_list,
2460+ struct drm_i915_gem_request,
2461+ list);
2462+
2463+ ret = i915_wait_request(dev, request->seqno);
2464+ if (ret)
2465+ break;
2466+
2467+ /* if waiting caused an object to become inactive,
2468+ * then loop around and wait for it. Otherwise, we
2469+ * assume that waiting freed and unbound something,
2470+ * so there should now be some space in the GTT
2471+ */
2472+ if (!list_empty(&dev_priv->mm.inactive_list))
2473+ continue;
2474+ break;
2475+ }
2476+
2477+ /* If we didn't have anything on the request list but there
2478+ * are buffers awaiting a flush, emit one and try again.
2479+ * When we wait on it, those buffers waiting for that flush
2480+ * will get moved to inactive.
2481+ */
2482+ if (!list_empty(&dev_priv->mm.flushing_list)) {
2483+ obj_priv = list_first_entry(&dev_priv->mm.flushing_list,
2484+ struct drm_i915_gem_object,
2485+ list);
2486+ obj = obj_priv->obj;
2487+
2488+ i915_gem_flush(dev,
2489+ obj->write_domain,
2490+ obj->write_domain);
2491+ i915_add_request(dev, obj->write_domain);
2492+
2493+ obj = NULL;
2494+ continue;
2495+ }
2496+
2497+ DRM_ERROR("inactive empty %d request empty %d "
2498+ "flushing empty %d\n",
2499+ list_empty(&dev_priv->mm.inactive_list),
2500+ list_empty(&dev_priv->mm.request_list),
2501+ list_empty(&dev_priv->mm.flushing_list));
2502+ /* If we didn't do any of the above, there's nothing to be done
2503+ * and we just can't fit it in.
2504+ */
2505+ return -ENOMEM;
2506+ }
2507+ return ret;
2508+}
2509+
2510+static int
2511+i915_gem_object_get_page_list(struct drm_gem_object *obj)
2512+{
2513+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
2514+ int page_count, i;
2515+ struct address_space *mapping;
2516+ struct inode *inode;
2517+ struct page *page;
2518+ int ret;
2519+
2520+ if (obj_priv->page_list)
2521+ return 0;
2522+
2523+ /* Get the list of pages out of our struct file. They'll be pinned
2524+ * at this point until we release them.
2525+ */
2526+ page_count = obj->size / PAGE_SIZE;
2527+ BUG_ON(obj_priv->page_list != NULL);
2528+ obj_priv->page_list = drm_calloc(page_count, sizeof(struct page *),
2529+ DRM_MEM_DRIVER);
2530+ if (obj_priv->page_list == NULL) {
2531+ DRM_ERROR("Faled to allocate page list\n");
2532+ return -ENOMEM;
2533+ }
2534+
2535+ inode = obj->filp->f_path.dentry->d_inode;
2536+ mapping = inode->i_mapping;
2537+ for (i = 0; i < page_count; i++) {
2538+ page = read_mapping_page(mapping, i, NULL);
2539+ if (IS_ERR(page)) {
2540+ ret = PTR_ERR(page);
2541+ DRM_ERROR("read_mapping_page failed: %d\n", ret);
2542+ i915_gem_object_free_page_list(obj);
2543+ return ret;
2544+ }
2545+ obj_priv->page_list[i] = page;
2546+ }
2547+ return 0;
2548+}
2549+
2550+/**
2551+ * Finds free space in the GTT aperture and binds the object there.
2552+ */
2553+static int
2554+i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment)
2555+{
2556+ struct drm_device *dev = obj->dev;
2557+ drm_i915_private_t *dev_priv = dev->dev_private;
2558+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
2559+ struct drm_mm_node *free_space;
2560+ int page_count, ret;
2561+
2562+ if (alignment == 0)
2563+ alignment = PAGE_SIZE;
2564+ if (alignment & (PAGE_SIZE - 1)) {
2565+ DRM_ERROR("Invalid object alignment requested %u\n", alignment);
2566+ return -EINVAL;
2567+ }
2568+
2569+ search_free:
2570+ free_space = drm_mm_search_free(&dev_priv->mm.gtt_space,
2571+ obj->size, alignment, 0);
2572+ if (free_space != NULL) {
2573+ obj_priv->gtt_space = drm_mm_get_block(free_space, obj->size,
2574+ alignment);
2575+ if (obj_priv->gtt_space != NULL) {
2576+ obj_priv->gtt_space->private = obj;
2577+ obj_priv->gtt_offset = obj_priv->gtt_space->start;
2578+ }
2579+ }
2580+ if (obj_priv->gtt_space == NULL) {
2581+ /* If the gtt is empty and we're still having trouble
2582+ * fitting our object in, we're out of memory.
2583+ */
2584+#if WATCH_LRU
2585+ DRM_INFO("%s: GTT full, evicting something\n", __func__);
2586+#endif
2587+ if (list_empty(&dev_priv->mm.inactive_list) &&
2588+ list_empty(&dev_priv->mm.flushing_list) &&
2589+ list_empty(&dev_priv->mm.active_list)) {
2590+ DRM_ERROR("GTT full, but LRU list empty\n");
2591+ return -ENOMEM;
2592+ }
2593+
2594+ ret = i915_gem_evict_something(dev);
2595+ if (ret != 0) {
2596+ DRM_ERROR("Failed to evict a buffer %d\n", ret);
2597+ return ret;
2598+ }
2599+ goto search_free;
2600+ }
2601+
2602+#if WATCH_BUF
2603+ DRM_INFO("Binding object of size %d at 0x%08x\n",
2604+ obj->size, obj_priv->gtt_offset);
2605+#endif
2606+ ret = i915_gem_object_get_page_list(obj);
2607+ if (ret) {
2608+ drm_mm_put_block(obj_priv->gtt_space);
2609+ obj_priv->gtt_space = NULL;
2610+ return ret;
2611+ }
2612+
2613+ page_count = obj->size / PAGE_SIZE;
2614+ /* Create an AGP memory structure pointing at our pages, and bind it
2615+ * into the GTT.
2616+ */
2617+ obj_priv->agp_mem = drm_agp_bind_pages(dev,
2618+ obj_priv->page_list,
2619+ page_count,
2620+ obj_priv->gtt_offset);
2621+ if (obj_priv->agp_mem == NULL) {
2622+ i915_gem_object_free_page_list(obj);
2623+ drm_mm_put_block(obj_priv->gtt_space);
2624+ obj_priv->gtt_space = NULL;
2625+ return -ENOMEM;
2626+ }
2627+ atomic_inc(&dev->gtt_count);
2628+ atomic_add(obj->size, &dev->gtt_memory);
2629+
2630+ /* Assert that the object is not currently in any GPU domain. As it
2631+ * wasn't in the GTT, there shouldn't be any way it could have been in
2632+ * a GPU cache
2633+ */
2634+ BUG_ON(obj->read_domains & ~(I915_GEM_DOMAIN_CPU|I915_GEM_DOMAIN_GTT));
2635+ BUG_ON(obj->write_domain & ~(I915_GEM_DOMAIN_CPU|I915_GEM_DOMAIN_GTT));
2636+
2637+ return 0;
2638+}
2639+
2640+void
2641+i915_gem_clflush_object(struct drm_gem_object *obj)
2642+{
2643+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
2644+
2645+ /* If we don't have a page list set up, then we're not pinned
2646+ * to GPU, and we can ignore the cache flush because it'll happen
2647+ * again at bind time.
2648+ */
2649+ if (obj_priv->page_list == NULL)
2650+ return;
2651+
2652+ drm_clflush_pages(obj_priv->page_list, obj->size / PAGE_SIZE);
2653+}
2654+
2655+/*
2656+ * Set the next domain for the specified object. This
2657+ * may not actually perform the necessary flushing/invaliding though,
2658+ * as that may want to be batched with other set_domain operations
2659+ *
2660+ * This is (we hope) the only really tricky part of gem. The goal
2661+ * is fairly simple -- track which caches hold bits of the object
2662+ * and make sure they remain coherent. A few concrete examples may
2663+ * help to explain how it works. For shorthand, we use the notation
2664+ * (read_domains, write_domain), e.g. (CPU, CPU) to indicate the
2665+ * a pair of read and write domain masks.
2666+ *
2667+ * Case 1: the batch buffer
2668+ *
2669+ * 1. Allocated
2670+ * 2. Written by CPU
2671+ * 3. Mapped to GTT
2672+ * 4. Read by GPU
2673+ * 5. Unmapped from GTT
2674+ * 6. Freed
2675+ *
2676+ * Let's take these a step at a time
2677+ *
2678+ * 1. Allocated
2679+ * Pages allocated from the kernel may still have
2680+ * cache contents, so we set them to (CPU, CPU) always.
2681+ * 2. Written by CPU (using pwrite)
2682+ * The pwrite function calls set_domain (CPU, CPU) and
2683+ * this function does nothing (as nothing changes)
2684+ * 3. Mapped by GTT
2685+ * This function asserts that the object is not
2686+ * currently in any GPU-based read or write domains
2687+ * 4. Read by GPU
2688+ * i915_gem_execbuffer calls set_domain (COMMAND, 0).
2689+ * As write_domain is zero, this function adds in the
2690+ * current read domains (CPU+COMMAND, 0).
2691+ * flush_domains is set to CPU.
2692+ * invalidate_domains is set to COMMAND
2693+ * clflush is run to get data out of the CPU caches
2694+ * then i915_dev_set_domain calls i915_gem_flush to
2695+ * emit an MI_FLUSH and drm_agp_chipset_flush
2696+ * 5. Unmapped from GTT
2697+ * i915_gem_object_unbind calls set_domain (CPU, CPU)
2698+ * flush_domains and invalidate_domains end up both zero
2699+ * so no flushing/invalidating happens
2700+ * 6. Freed
2701+ * yay, done
2702+ *
2703+ * Case 2: The shared render buffer
2704+ *
2705+ * 1. Allocated
2706+ * 2. Mapped to GTT
2707+ * 3. Read/written by GPU
2708+ * 4. set_domain to (CPU,CPU)
2709+ * 5. Read/written by CPU
2710+ * 6. Read/written by GPU
2711+ *
2712+ * 1. Allocated
2713+ * Same as last example, (CPU, CPU)
2714+ * 2. Mapped to GTT
2715+ * Nothing changes (assertions find that it is not in the GPU)
2716+ * 3. Read/written by GPU
2717+ * execbuffer calls set_domain (RENDER, RENDER)
2718+ * flush_domains gets CPU
2719+ * invalidate_domains gets GPU
2720+ * clflush (obj)
2721+ * MI_FLUSH and drm_agp_chipset_flush
2722+ * 4. set_domain (CPU, CPU)
2723+ * flush_domains gets GPU
2724+ * invalidate_domains gets CPU
2725+ * wait_rendering (obj) to make sure all drawing is complete.
2726+ * This will include an MI_FLUSH to get the data from GPU
2727+ * to memory
2728+ * clflush (obj) to invalidate the CPU cache
2729+ * Another MI_FLUSH in i915_gem_flush (eliminate this somehow?)
2730+ * 5. Read/written by CPU
2731+ * cache lines are loaded and dirtied
2732+ * 6. Read written by GPU
2733+ * Same as last GPU access
2734+ *
2735+ * Case 3: The constant buffer
2736+ *
2737+ * 1. Allocated
2738+ * 2. Written by CPU
2739+ * 3. Read by GPU
2740+ * 4. Updated (written) by CPU again
2741+ * 5. Read by GPU
2742+ *
2743+ * 1. Allocated
2744+ * (CPU, CPU)
2745+ * 2. Written by CPU
2746+ * (CPU, CPU)
2747+ * 3. Read by GPU
2748+ * (CPU+RENDER, 0)
2749+ * flush_domains = CPU
2750+ * invalidate_domains = RENDER
2751+ * clflush (obj)
2752+ * MI_FLUSH
2753+ * drm_agp_chipset_flush
2754+ * 4. Updated (written) by CPU again
2755+ * (CPU, CPU)
2756+ * flush_domains = 0 (no previous write domain)
2757+ * invalidate_domains = 0 (no new read domains)
2758+ * 5. Read by GPU
2759+ * (CPU+RENDER, 0)
2760+ * flush_domains = CPU
2761+ * invalidate_domains = RENDER
2762+ * clflush (obj)
2763+ * MI_FLUSH
2764+ * drm_agp_chipset_flush
2765+ */
2766+static int
2767+i915_gem_object_set_domain(struct drm_gem_object *obj,
2768+ uint32_t read_domains,
2769+ uint32_t write_domain)
2770+{
2771+ struct drm_device *dev = obj->dev;
2772+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
2773+ uint32_t invalidate_domains = 0;
2774+ uint32_t flush_domains = 0;
2775+ int ret;
2776+
2777+#if WATCH_BUF
2778+ DRM_INFO("%s: object %p read %08x -> %08x write %08x -> %08x\n",
2779+ __func__, obj,
2780+ obj->read_domains, read_domains,
2781+ obj->write_domain, write_domain);
2782+#endif
2783+ /*
2784+ * If the object isn't moving to a new write domain,
2785+ * let the object stay in multiple read domains
2786+ */
2787+ if (write_domain == 0)
2788+ read_domains |= obj->read_domains;
2789+ else
2790+ obj_priv->dirty = 1;
2791+
2792+ /*
2793+ * Flush the current write domain if
2794+ * the new read domains don't match. Invalidate
2795+ * any read domains which differ from the old
2796+ * write domain
2797+ */
2798+ if (obj->write_domain && obj->write_domain != read_domains) {
2799+ flush_domains |= obj->write_domain;
2800+ invalidate_domains |= read_domains & ~obj->write_domain;
2801+ }
2802+ /*
2803+ * Invalidate any read caches which may have
2804+ * stale data. That is, any new read domains.
2805+ */
2806+ invalidate_domains |= read_domains & ~obj->read_domains;
2807+ if ((flush_domains | invalidate_domains) & I915_GEM_DOMAIN_CPU) {
2808+#if WATCH_BUF
2809+ DRM_INFO("%s: CPU domain flush %08x invalidate %08x\n",
2810+ __func__, flush_domains, invalidate_domains);
2811+#endif
2812+ /*
2813+ * If we're invaliding the CPU cache and flushing a GPU cache,
2814+ * then pause for rendering so that the GPU caches will be
2815+ * flushed before the cpu cache is invalidated
2816+ */
2817+ if ((invalidate_domains & I915_GEM_DOMAIN_CPU) &&
2818+ (flush_domains & ~(I915_GEM_DOMAIN_CPU |
2819+ I915_GEM_DOMAIN_GTT))) {
2820+ ret = i915_gem_object_wait_rendering(obj);
2821+ if (ret)
2822+ return ret;
2823+ }
2824+ i915_gem_clflush_object(obj);
2825+ }
2826+
2827+ if ((write_domain | flush_domains) != 0)
2828+ obj->write_domain = write_domain;
2829+
2830+ /* If we're invalidating the CPU domain, clear the per-page CPU
2831+ * domain list as well.
2832+ */
2833+ if (obj_priv->page_cpu_valid != NULL &&
2834+ (obj->read_domains & I915_GEM_DOMAIN_CPU) &&
2835+ ((read_domains & I915_GEM_DOMAIN_CPU) == 0)) {
2836+ memset(obj_priv->page_cpu_valid, 0, obj->size / PAGE_SIZE);
2837+ }
2838+ obj->read_domains = read_domains;
2839+
2840+ dev->invalidate_domains |= invalidate_domains;
2841+ dev->flush_domains |= flush_domains;
2842+#if WATCH_BUF
2843+ DRM_INFO("%s: read %08x write %08x invalidate %08x flush %08x\n",
2844+ __func__,
2845+ obj->read_domains, obj->write_domain,
2846+ dev->invalidate_domains, dev->flush_domains);
2847+#endif
2848+ return 0;
2849+}
2850+
2851+/**
2852+ * Set the read/write domain on a range of the object.
2853+ *
2854+ * Currently only implemented for CPU reads, otherwise drops to normal
2855+ * i915_gem_object_set_domain().
2856+ */
2857+static int
2858+i915_gem_object_set_domain_range(struct drm_gem_object *obj,
2859+ uint64_t offset,
2860+ uint64_t size,
2861+ uint32_t read_domains,
2862+ uint32_t write_domain)
2863+{
2864+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
2865+ int ret, i;
2866+
2867+ if (obj->read_domains & I915_GEM_DOMAIN_CPU)
2868+ return 0;
2869+
2870+ if (read_domains != I915_GEM_DOMAIN_CPU ||
2871+ write_domain != 0)
2872+ return i915_gem_object_set_domain(obj,
2873+ read_domains, write_domain);
2874+
2875+ /* Wait on any GPU rendering to the object to be flushed. */
2876+ if (obj->write_domain & ~(I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT)) {
2877+ ret = i915_gem_object_wait_rendering(obj);
2878+ if (ret)
2879+ return ret;
2880+ }
2881+
2882+ if (obj_priv->page_cpu_valid == NULL) {
2883+ obj_priv->page_cpu_valid = drm_calloc(1, obj->size / PAGE_SIZE,
2884+ DRM_MEM_DRIVER);
2885+ }
2886+
2887+ /* Flush the cache on any pages that are still invalid from the CPU's
2888+ * perspective.
2889+ */
2890+ for (i = offset / PAGE_SIZE; i < (offset + size - 1) / PAGE_SIZE; i++) {
2891+ if (obj_priv->page_cpu_valid[i])
2892+ continue;
2893+
2894+ drm_clflush_pages(obj_priv->page_list + i, 1);
2895+
2896+ obj_priv->page_cpu_valid[i] = 1;
2897+ }
2898+
2899+ return 0;
2900+}
2901+
2902+/**
2903+ * Once all of the objects have been set in the proper domain,
2904+ * perform the necessary flush and invalidate operations.
2905+ *
2906+ * Returns the write domains flushed, for use in flush tracking.
2907+ */
2908+static uint32_t
2909+i915_gem_dev_set_domain(struct drm_device *dev)
2910+{
2911+ uint32_t flush_domains = dev->flush_domains;
2912+
2913+ /*
2914+ * Now that all the buffers are synced to the proper domains,
2915+ * flush and invalidate the collected domains
2916+ */
2917+ if (dev->invalidate_domains | dev->flush_domains) {
2918+#if WATCH_EXEC
2919+ DRM_INFO("%s: invalidate_domains %08x flush_domains %08x\n",
2920+ __func__,
2921+ dev->invalidate_domains,
2922+ dev->flush_domains);
2923+#endif
2924+ i915_gem_flush(dev,
2925+ dev->invalidate_domains,
2926+ dev->flush_domains);
2927+ dev->invalidate_domains = 0;
2928+ dev->flush_domains = 0;
2929+ }
2930+
2931+ return flush_domains;
2932+}
2933+
2934+/**
2935+ * Pin an object to the GTT and evaluate the relocations landing in it.
2936+ */
2937+static int
2938+i915_gem_object_pin_and_relocate(struct drm_gem_object *obj,
2939+ struct drm_file *file_priv,
2940+ struct drm_i915_gem_exec_object *entry)
2941+{
2942+ struct drm_device *dev = obj->dev;
2943+ struct drm_i915_gem_relocation_entry reloc;
2944+ struct drm_i915_gem_relocation_entry __user *relocs;
2945+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
2946+ int i, ret;
2947+ uint32_t last_reloc_offset = -1;
2948+ void *reloc_page = NULL;
2949+
2950+ /* Choose the GTT offset for our buffer and put it there. */
2951+ ret = i915_gem_object_pin(obj, (uint32_t) entry->alignment);
2952+ if (ret)
2953+ return ret;
2954+
2955+ entry->offset = obj_priv->gtt_offset;
2956+
2957+ relocs = (struct drm_i915_gem_relocation_entry __user *)
2958+ (uintptr_t) entry->relocs_ptr;
2959+ /* Apply the relocations, using the GTT aperture to avoid cache
2960+ * flushing requirements.
2961+ */
2962+ for (i = 0; i < entry->relocation_count; i++) {
2963+ struct drm_gem_object *target_obj;
2964+ struct drm_i915_gem_object *target_obj_priv;
2965+ uint32_t reloc_val, reloc_offset, *reloc_entry;
2966+ int ret;
2967+
2968+ ret = copy_from_user(&reloc, relocs + i, sizeof(reloc));
2969+ if (ret != 0) {
2970+ i915_gem_object_unpin(obj);
2971+ return ret;
2972+ }
2973+
2974+ target_obj = drm_gem_object_lookup(obj->dev, file_priv,
2975+ reloc.target_handle);
2976+ if (target_obj == NULL) {
2977+ i915_gem_object_unpin(obj);
2978+ return -EBADF;
2979+ }
2980+ target_obj_priv = target_obj->driver_private;
2981+
2982+ /* The target buffer should have appeared before us in the
2983+ * exec_object list, so it should have a GTT space bound by now.
2984+ */
2985+ if (target_obj_priv->gtt_space == NULL) {
2986+ DRM_ERROR("No GTT space found for object %d\n",
2987+ reloc.target_handle);
2988+ drm_gem_object_unreference(target_obj);
2989+ i915_gem_object_unpin(obj);
2990+ return -EINVAL;
2991+ }
2992+
2993+ if (reloc.offset > obj->size - 4) {
2994+ DRM_ERROR("Relocation beyond object bounds: "
2995+ "obj %p target %d offset %d size %d.\n",
2996+ obj, reloc.target_handle,
2997+ (int) reloc.offset, (int) obj->size);
2998+ drm_gem_object_unreference(target_obj);
2999+ i915_gem_object_unpin(obj);
3000+ return -EINVAL;
3001+ }
3002+ if (reloc.offset & 3) {
3003+ DRM_ERROR("Relocation not 4-byte aligned: "
3004+ "obj %p target %d offset %d.\n",
3005+ obj, reloc.target_handle,
3006+ (int) reloc.offset);
3007+ drm_gem_object_unreference(target_obj);
3008+ i915_gem_object_unpin(obj);
3009+ return -EINVAL;
3010+ }
3011+
3012+ if (reloc.write_domain && target_obj->pending_write_domain &&
3013+ reloc.write_domain != target_obj->pending_write_domain) {
3014+ DRM_ERROR("Write domain conflict: "
3015+ "obj %p target %d offset %d "
3016+ "new %08x old %08x\n",
3017+ obj, reloc.target_handle,
3018+ (int) reloc.offset,
3019+ reloc.write_domain,
3020+ target_obj->pending_write_domain);
3021+ drm_gem_object_unreference(target_obj);
3022+ i915_gem_object_unpin(obj);
3023+ return -EINVAL;
3024+ }
3025+
3026+#if WATCH_RELOC
3027+ DRM_INFO("%s: obj %p offset %08x target %d "
3028+ "read %08x write %08x gtt %08x "
3029+ "presumed %08x delta %08x\n",
3030+ __func__,
3031+ obj,
3032+ (int) reloc.offset,
3033+ (int) reloc.target_handle,
3034+ (int) reloc.read_domains,
3035+ (int) reloc.write_domain,
3036+ (int) target_obj_priv->gtt_offset,
3037+ (int) reloc.presumed_offset,
3038+ reloc.delta);
3039+#endif
3040+
3041+ target_obj->pending_read_domains |= reloc.read_domains;
3042+ target_obj->pending_write_domain |= reloc.write_domain;
3043+
3044+ /* If the relocation already has the right value in it, no
3045+ * more work needs to be done.
3046+ */
3047+ if (target_obj_priv->gtt_offset == reloc.presumed_offset) {
3048+ drm_gem_object_unreference(target_obj);
3049+ continue;
3050+ }
3051+
3052+ /* Now that we're going to actually write some data in,
3053+ * make sure that any rendering using this buffer's contents
3054+ * is completed.
3055+ */
3056+ i915_gem_object_wait_rendering(obj);
3057+
3058+ /* As we're writing through the gtt, flush
3059+ * any CPU writes before we write the relocations
3060+ */
3061+ if (obj->write_domain & I915_GEM_DOMAIN_CPU) {
3062+ i915_gem_clflush_object(obj);
3063+ drm_agp_chipset_flush(dev);
3064+ obj->write_domain = 0;
3065+ }
3066+
3067+ /* Map the page containing the relocation we're going to
3068+ * perform.
3069+ */
3070+ reloc_offset = obj_priv->gtt_offset + reloc.offset;
3071+ if (reloc_page == NULL ||
3072+ (last_reloc_offset & ~(PAGE_SIZE - 1)) !=
3073+ (reloc_offset & ~(PAGE_SIZE - 1))) {
3074+ if (reloc_page != NULL)
3075+ iounmap(reloc_page);
3076+
3077+ reloc_page = ioremap(dev->agp->base +
3078+ (reloc_offset & ~(PAGE_SIZE - 1)),
3079+ PAGE_SIZE);
3080+ last_reloc_offset = reloc_offset;
3081+ if (reloc_page == NULL) {
3082+ drm_gem_object_unreference(target_obj);
3083+ i915_gem_object_unpin(obj);
3084+ return -ENOMEM;
3085+ }
3086+ }
3087+
3088+ reloc_entry = (uint32_t *)((char *)reloc_page +
3089+ (reloc_offset & (PAGE_SIZE - 1)));
3090+ reloc_val = target_obj_priv->gtt_offset + reloc.delta;
3091+
3092+#if WATCH_BUF
3093+ DRM_INFO("Applied relocation: %p@0x%08x %08x -> %08x\n",
3094+ obj, (unsigned int) reloc.offset,
3095+ readl(reloc_entry), reloc_val);
3096+#endif
3097+ writel(reloc_val, reloc_entry);
3098+
3099+ /* Write the updated presumed offset for this entry back out
3100+ * to the user.
3101+ */
3102+ reloc.presumed_offset = target_obj_priv->gtt_offset;
3103+ ret = copy_to_user(relocs + i, &reloc, sizeof(reloc));
3104+ if (ret != 0) {
3105+ drm_gem_object_unreference(target_obj);
3106+ i915_gem_object_unpin(obj);
3107+ return ret;
3108+ }
3109+
3110+ drm_gem_object_unreference(target_obj);
3111+ }
3112+
3113+ if (reloc_page != NULL)
3114+ iounmap(reloc_page);
3115+
3116+#if WATCH_BUF
3117+ if (0)
3118+ i915_gem_dump_object(obj, 128, __func__, ~0);
3119+#endif
3120+ return 0;
3121+}
3122+
3123+/** Dispatch a batchbuffer to the ring
3124+ */
3125+static int
3126+i915_dispatch_gem_execbuffer(struct drm_device *dev,
3127+ struct drm_i915_gem_execbuffer *exec,
3128+ uint64_t exec_offset)
3129+{
3130+ drm_i915_private_t *dev_priv = dev->dev_private;
3131+ struct drm_clip_rect __user *boxes = (struct drm_clip_rect __user *)
3132+ (uintptr_t) exec->cliprects_ptr;
3133+ int nbox = exec->num_cliprects;
3134+ int i = 0, count;
3135+ uint32_t exec_start, exec_len;
3136+ RING_LOCALS;
3137+
3138+ exec_start = (uint32_t) exec_offset + exec->batch_start_offset;
3139+ exec_len = (uint32_t) exec->batch_len;
3140+
3141+ if ((exec_start | exec_len) & 0x7) {
3142+ DRM_ERROR("alignment\n");
3143+ return -EINVAL;
3144+ }
3145+
3146+ if (!exec_start)
3147+ return -EINVAL;
3148+
3149+ count = nbox ? nbox : 1;
3150+
3151+ for (i = 0; i < count; i++) {
3152+ if (i < nbox) {
3153+ int ret = i915_emit_box(dev, boxes, i,
3154+ exec->DR1, exec->DR4);
3155+ if (ret)
3156+ return ret;
3157+ }
3158+
3159+ if (IS_I830(dev) || IS_845G(dev)) {
3160+ BEGIN_LP_RING(4);
3161+ OUT_RING(MI_BATCH_BUFFER);
3162+ OUT_RING(exec_start | MI_BATCH_NON_SECURE);
3163+ OUT_RING(exec_start + exec_len - 4);
3164+ OUT_RING(0);
3165+ ADVANCE_LP_RING();
3166+ } else {
3167+ BEGIN_LP_RING(2);
3168+ if (IS_I965G(dev)) {
3169+ OUT_RING(MI_BATCH_BUFFER_START |
3170+ (2 << 6) |
3171+ MI_BATCH_NON_SECURE_I965);
3172+ OUT_RING(exec_start);
3173+ } else {
3174+ OUT_RING(MI_BATCH_BUFFER_START |
3175+ (2 << 6));
3176+ OUT_RING(exec_start | MI_BATCH_NON_SECURE);
3177+ }
3178+ ADVANCE_LP_RING();
3179+ }
3180+ }
3181+
3182+ /* XXX breadcrumb */
3183+ return 0;
3184+}
3185+
3186+/* Throttle our rendering by waiting until the ring has completed our requests
3187+ * emitted over 20 msec ago.
3188+ *
3189+ * This should get us reasonable parallelism between CPU and GPU but also
3190+ * relatively low latency when blocking on a particular request to finish.
3191+ */
3192+static int
3193+i915_gem_ring_throttle(struct drm_device *dev, struct drm_file *file_priv)
3194+{
3195+ struct drm_i915_file_private *i915_file_priv = file_priv->driver_priv;
3196+ int ret = 0;
3197+ uint32_t seqno;
3198+
3199+ mutex_lock(&dev->struct_mutex);
3200+ seqno = i915_file_priv->mm.last_gem_throttle_seqno;
3201+ i915_file_priv->mm.last_gem_throttle_seqno =
3202+ i915_file_priv->mm.last_gem_seqno;
3203+ if (seqno)
3204+ ret = i915_wait_request(dev, seqno);
3205+ mutex_unlock(&dev->struct_mutex);
3206+ return ret;
3207+}
3208+
3209+int
3210+i915_gem_execbuffer(struct drm_device *dev, void *data,
3211+ struct drm_file *file_priv)
3212+{
3213+ drm_i915_private_t *dev_priv = dev->dev_private;
3214+ struct drm_i915_file_private *i915_file_priv = file_priv->driver_priv;
3215+ struct drm_i915_gem_execbuffer *args = data;
3216+ struct drm_i915_gem_exec_object *exec_list = NULL;
3217+ struct drm_gem_object **object_list = NULL;
3218+ struct drm_gem_object *batch_obj;
3219+ int ret, i, pinned = 0;
3220+ uint64_t exec_offset;
3221+ uint32_t seqno, flush_domains, pre_flush_domains;
3222+
3223+#if WATCH_EXEC
3224+ DRM_INFO("buffers_ptr %d buffer_count %d len %08x\n",
3225+ (int) args->buffers_ptr, args->buffer_count, args->batch_len);
3226+#endif
3227+
3228+ /* Copy in the exec list from userland */
3229+ exec_list = drm_calloc(sizeof(*exec_list), args->buffer_count,
3230+ DRM_MEM_DRIVER);
3231+ object_list = drm_calloc(sizeof(*object_list), args->buffer_count,
3232+ DRM_MEM_DRIVER);
3233+ if (exec_list == NULL || object_list == NULL) {
3234+ DRM_ERROR("Failed to allocate exec or object list "
3235+ "for %d buffers\n",
3236+ args->buffer_count);
3237+ ret = -ENOMEM;
3238+ goto pre_mutex_err;
3239+ }
3240+ ret = copy_from_user(exec_list,
3241+ (struct drm_i915_relocation_entry __user *)
3242+ (uintptr_t) args->buffers_ptr,
3243+ sizeof(*exec_list) * args->buffer_count);
3244+ if (ret != 0) {
3245+ DRM_ERROR("copy %d exec entries failed %d\n",
3246+ args->buffer_count, ret);
3247+ goto pre_mutex_err;
3248+ }
3249+
3250+ mutex_lock(&dev->struct_mutex);
3251+
3252+ i915_verify_inactive(dev, __FILE__, __LINE__);
3253+
3254+ if (dev_priv->mm.wedged) {
3255+ DRM_ERROR("Execbuf while wedged\n");
3256+ mutex_unlock(&dev->struct_mutex);
3257+ return -EIO;
3258+ }
3259+
3260+ if (dev_priv->mm.suspended) {
3261+ DRM_ERROR("Execbuf while VT-switched.\n");
3262+ mutex_unlock(&dev->struct_mutex);
3263+ return -EBUSY;
3264+ }
3265+
3266+ /* Zero the gloabl flush/invalidate flags. These
3267+ * will be modified as each object is bound to the
3268+ * gtt
3269+ */
3270+ dev->invalidate_domains = 0;
3271+ dev->flush_domains = 0;
3272+
3273+ /* Look up object handles and perform the relocations */
3274+ for (i = 0; i < args->buffer_count; i++) {
3275+ object_list[i] = drm_gem_object_lookup(dev, file_priv,
3276+ exec_list[i].handle);
3277+ if (object_list[i] == NULL) {
3278+ DRM_ERROR("Invalid object handle %d at index %d\n",
3279+ exec_list[i].handle, i);
3280+ ret = -EBADF;
3281+ goto err;
3282+ }
3283+
3284+ object_list[i]->pending_read_domains = 0;
3285+ object_list[i]->pending_write_domain = 0;
3286+ ret = i915_gem_object_pin_and_relocate(object_list[i],
3287+ file_priv,
3288+ &exec_list[i]);
3289+ if (ret) {
3290+ DRM_ERROR("object bind and relocate failed %d\n", ret);
3291+ goto err;
3292+ }
3293+ pinned = i + 1;
3294+ }
3295+
3296+ /* Set the pending read domains for the batch buffer to COMMAND */
3297+ batch_obj = object_list[args->buffer_count-1];
3298+ batch_obj->pending_read_domains = I915_GEM_DOMAIN_COMMAND;
3299+ batch_obj->pending_write_domain = 0;
3300+
3301+ i915_verify_inactive(dev, __FILE__, __LINE__);
3302+
3303+ for (i = 0; i < args->buffer_count; i++) {
3304+ struct drm_gem_object *obj = object_list[i];
3305+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
3306+
3307+ if (obj_priv->gtt_space == NULL) {
3308+ /* We evicted the buffer in the process of validating
3309+ * our set of buffers in. We could try to recover by
3310+ * kicking them everything out and trying again from
3311+ * the start.
3312+ */
3313+ ret = -ENOMEM;
3314+ goto err;
3315+ }
3316+
3317+ /* make sure all previous memory operations have passed */
3318+ ret = i915_gem_object_set_domain(obj,
3319+ obj->pending_read_domains,
3320+ obj->pending_write_domain);
3321+ if (ret)
3322+ goto err;
3323+ }
3324+
3325+ i915_verify_inactive(dev, __FILE__, __LINE__);
3326+
3327+ /* Flush/invalidate caches and chipset buffer */
3328+ flush_domains = i915_gem_dev_set_domain(dev);
3329+
3330+ i915_verify_inactive(dev, __FILE__, __LINE__);
3331+
3332+#if WATCH_COHERENCY
3333+ for (i = 0; i < args->buffer_count; i++) {
3334+ i915_gem_object_check_coherency(object_list[i],
3335+ exec_list[i].handle);
3336+ }
3337+#endif
3338+
3339+ exec_offset = exec_list[args->buffer_count - 1].offset;
3340+
3341+#if WATCH_EXEC
3342+ i915_gem_dump_object(object_list[args->buffer_count - 1],
3343+ args->batch_len,
3344+ __func__,
3345+ ~0);
3346+#endif
3347+
3348+ pre_flush_domains = flush_domains;
3349+
3350+ /* Exec the batchbuffer */
3351+ ret = i915_dispatch_gem_execbuffer(dev, args, exec_offset);
3352+ if (ret) {
3353+ DRM_ERROR("dispatch failed %d\n", ret);
3354+ goto err;
3355+ }
3356+
3357+ /*
3358+ * Ensure that the commands in the batch buffer are
3359+ * finished before the interrupt fires
3360+ */
3361+ flush_domains |= i915_retire_commands(dev);
3362+
3363+ i915_verify_inactive(dev, __FILE__, __LINE__);
3364+
3365+ /*
3366+ * Get a seqno representing the execution of the current buffer,
3367+ * which we can wait on. We would like to mitigate these interrupts,
3368+ * likely by only creating seqnos occasionally (so that we have
3369+ * *some* interrupts representing completion of buffers that we can
3370+ * wait on when trying to clear up gtt space).
3371+ */
3372+ seqno = i915_add_request(dev, flush_domains);
3373+ BUG_ON(seqno == 0);
3374+ i915_file_priv->mm.last_gem_seqno = seqno;
3375+ for (i = 0; i < args->buffer_count; i++) {
3376+ struct drm_gem_object *obj = object_list[i];
3377+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
3378+
3379+ if (pre_flush_domains & obj->pending_write_domain &
3380+ ~(I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT)) {
3381+ /* If we had a batchbuffer that resulted in a GPU
3382+ * domain being flushed before execution, followed by
3383+ * execution that resulted in the write_domain being
3384+ * set, then when that request is retired the
3385+ * write_domain would be incorrectly cleared. We're not
3386+ * sure that this can be triggered.
3387+ */
3388+ DRM_ERROR("Going to lose the write domain on "
3389+ "obj %d size %d\n",
3390+ exec_list[i].handle, obj->size);
3391+ }
3392+
3393+ i915_gem_object_move_to_active(obj);
3394+ obj_priv->last_rendering_seqno = seqno;
3395+#if WATCH_LRU
3396+ DRM_INFO("%s: move to exec list %p\n", __func__, obj);
3397+#endif
3398+ }
3399+#if WATCH_LRU
3400+ i915_dump_lru(dev, __func__);
3401+#endif
3402+
3403+ i915_verify_inactive(dev, __FILE__, __LINE__);
3404+
3405+ /* Copy the new buffer offsets back to the user's exec list. */
3406+ ret = copy_to_user((struct drm_i915_relocation_entry __user *)
3407+ (uintptr_t) args->buffers_ptr,
3408+ exec_list,
3409+ sizeof(*exec_list) * args->buffer_count);
3410+ if (ret)
3411+ DRM_ERROR("failed to copy %d exec entries "
3412+ "back to user (%d)\n",
3413+ args->buffer_count, ret);
3414+err:
3415+ if (object_list != NULL) {
3416+ for (i = 0; i < pinned; i++)
3417+ i915_gem_object_unpin(object_list[i]);
3418+
3419+ for (i = 0; i < args->buffer_count; i++)
3420+ drm_gem_object_unreference(object_list[i]);
3421+ }
3422+ mutex_unlock(&dev->struct_mutex);
3423+
3424+pre_mutex_err:
3425+ drm_free(object_list, sizeof(*object_list) * args->buffer_count,
3426+ DRM_MEM_DRIVER);
3427+ drm_free(exec_list, sizeof(*exec_list) * args->buffer_count,
3428+ DRM_MEM_DRIVER);
3429+
3430+ return ret;
3431+}
3432+
3433+int
3434+i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment)
3435+{
3436+ struct drm_device *dev = obj->dev;
3437+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
3438+ int ret;
3439+
3440+ i915_verify_inactive(dev, __FILE__, __LINE__);
3441+ if (obj_priv->gtt_space == NULL) {
3442+ ret = i915_gem_object_bind_to_gtt(obj, alignment);
3443+ if (ret != 0) {
3444+ DRM_ERROR("Failure to bind: %d", ret);
3445+ return ret;
3446+ }
3447+ }
3448+ obj_priv->pin_count++;
3449+
3450+ /* If the object is not active and not pending a flush,
3451+ * remove it from the inactive list
3452+ */
3453+ if (obj_priv->pin_count == 1) {
3454+ atomic_inc(&dev->pin_count);
3455+ atomic_add(obj->size, &dev->pin_memory);
3456+ if (!obj_priv->active &&
3457+ (obj->write_domain & ~(I915_GEM_DOMAIN_CPU |
3458+ I915_GEM_DOMAIN_GTT)) == 0 &&
3459+ !list_empty(&obj_priv->list))
3460+ list_del_init(&obj_priv->list);
3461+ }
3462+ i915_verify_inactive(dev, __FILE__, __LINE__);
3463+
3464+ return 0;
3465+}
3466+
3467+void
3468+i915_gem_object_unpin(struct drm_gem_object *obj)
3469+{
3470+ struct drm_device *dev = obj->dev;
3471+ drm_i915_private_t *dev_priv = dev->dev_private;
3472+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
3473+
3474+ i915_verify_inactive(dev, __FILE__, __LINE__);
3475+ obj_priv->pin_count--;
3476+ BUG_ON(obj_priv->pin_count < 0);
3477+ BUG_ON(obj_priv->gtt_space == NULL);
3478+
3479+ /* If the object is no longer pinned, and is
3480+ * neither active nor being flushed, then stick it on
3481+ * the inactive list
3482+ */
3483+ if (obj_priv->pin_count == 0) {
3484+ if (!obj_priv->active &&
3485+ (obj->write_domain & ~(I915_GEM_DOMAIN_CPU |
3486+ I915_GEM_DOMAIN_GTT)) == 0)
3487+ list_move_tail(&obj_priv->list,
3488+ &dev_priv->mm.inactive_list);
3489+ atomic_dec(&dev->pin_count);
3490+ atomic_sub(obj->size, &dev->pin_memory);
3491+ }
3492+ i915_verify_inactive(dev, __FILE__, __LINE__);
3493+}
3494+
3495+int
3496+i915_gem_pin_ioctl(struct drm_device *dev, void *data,
3497+ struct drm_file *file_priv)
3498+{
3499+ struct drm_i915_gem_pin *args = data;
3500+ struct drm_gem_object *obj;
3501+ struct drm_i915_gem_object *obj_priv;
3502+ int ret;
3503+
3504+ mutex_lock(&dev->struct_mutex);
3505+
3506+ obj = drm_gem_object_lookup(dev, file_priv, args->handle);
3507+ if (obj == NULL) {
3508+ DRM_ERROR("Bad handle in i915_gem_pin_ioctl(): %d\n",
3509+ args->handle);
3510+ mutex_unlock(&dev->struct_mutex);
3511+ return -EBADF;
3512+ }
3513+ obj_priv = obj->driver_private;
3514+
3515+ ret = i915_gem_object_pin(obj, args->alignment);
3516+ if (ret != 0) {
3517+ drm_gem_object_unreference(obj);
3518+ mutex_unlock(&dev->struct_mutex);
3519+ return ret;
3520+ }
3521+
3522+ /* XXX - flush the CPU caches for pinned objects
3523+ * as the X server doesn't manage domains yet
3524+ */
3525+ if (obj->write_domain & I915_GEM_DOMAIN_CPU) {
3526+ i915_gem_clflush_object(obj);
3527+ drm_agp_chipset_flush(dev);
3528+ obj->write_domain = 0;
3529+ }
3530+ args->offset = obj_priv->gtt_offset;
3531+ drm_gem_object_unreference(obj);
3532+ mutex_unlock(&dev->struct_mutex);
3533+
3534+ return 0;
3535+}
3536+
3537+int
3538+i915_gem_unpin_ioctl(struct drm_device *dev, void *data,
3539+ struct drm_file *file_priv)
3540+{
3541+ struct drm_i915_gem_pin *args = data;
3542+ struct drm_gem_object *obj;
3543+
3544+ mutex_lock(&dev->struct_mutex);
3545+
3546+ obj = drm_gem_object_lookup(dev, file_priv, args->handle);
3547+ if (obj == NULL) {
3548+ DRM_ERROR("Bad handle in i915_gem_unpin_ioctl(): %d\n",
3549+ args->handle);
3550+ mutex_unlock(&dev->struct_mutex);
3551+ return -EBADF;
3552+ }
3553+
3554+ i915_gem_object_unpin(obj);
3555+
3556+ drm_gem_object_unreference(obj);
3557+ mutex_unlock(&dev->struct_mutex);
3558+ return 0;
3559+}
3560+
3561+int
3562+i915_gem_busy_ioctl(struct drm_device *dev, void *data,
3563+ struct drm_file *file_priv)
3564+{
3565+ struct drm_i915_gem_busy *args = data;
3566+ struct drm_gem_object *obj;
3567+ struct drm_i915_gem_object *obj_priv;
3568+
3569+ mutex_lock(&dev->struct_mutex);
3570+ obj = drm_gem_object_lookup(dev, file_priv, args->handle);
3571+ if (obj == NULL) {
3572+ DRM_ERROR("Bad handle in i915_gem_busy_ioctl(): %d\n",
3573+ args->handle);
3574+ mutex_unlock(&dev->struct_mutex);
3575+ return -EBADF;
3576+ }
3577+
3578+ obj_priv = obj->driver_private;
3579+ args->busy = obj_priv->active;
3580+
3581+ drm_gem_object_unreference(obj);
3582+ mutex_unlock(&dev->struct_mutex);
3583+ return 0;
3584+}
3585+
3586+int
3587+i915_gem_throttle_ioctl(struct drm_device *dev, void *data,
3588+ struct drm_file *file_priv)
3589+{
3590+ return i915_gem_ring_throttle(dev, file_priv);
3591+}
3592+
3593+int i915_gem_init_object(struct drm_gem_object *obj)
3594+{
3595+ struct drm_i915_gem_object *obj_priv;
3596+
3597+ obj_priv = drm_calloc(1, sizeof(*obj_priv), DRM_MEM_DRIVER);
3598+ if (obj_priv == NULL)
3599+ return -ENOMEM;
3600+
3601+ /*
3602+ * We've just allocated pages from the kernel,
3603+ * so they've just been written by the CPU with
3604+ * zeros. They'll need to be clflushed before we
3605+ * use them with the GPU.
3606+ */
3607+ obj->write_domain = I915_GEM_DOMAIN_CPU;
3608+ obj->read_domains = I915_GEM_DOMAIN_CPU;
3609+
3610+ obj->driver_private = obj_priv;
3611+ obj_priv->obj = obj;
3612+ INIT_LIST_HEAD(&obj_priv->list);
3613+ return 0;
3614+}
3615+
3616+void i915_gem_free_object(struct drm_gem_object *obj)
3617+{
3618+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
3619+
3620+ while (obj_priv->pin_count > 0)
3621+ i915_gem_object_unpin(obj);
3622+
3623+ i915_gem_object_unbind(obj);
3624+
3625+ drm_free(obj_priv->page_cpu_valid, 1, DRM_MEM_DRIVER);
3626+ drm_free(obj->driver_private, 1, DRM_MEM_DRIVER);
3627+}
3628+
3629+static int
3630+i915_gem_set_domain(struct drm_gem_object *obj,
3631+ struct drm_file *file_priv,
3632+ uint32_t read_domains,
3633+ uint32_t write_domain)
3634+{
3635+ struct drm_device *dev = obj->dev;
3636+ int ret;
3637+ uint32_t flush_domains;
3638+
3639+ BUG_ON(!mutex_is_locked(&dev->struct_mutex));
3640+
3641+ ret = i915_gem_object_set_domain(obj, read_domains, write_domain);
3642+ if (ret)
3643+ return ret;
3644+ flush_domains = i915_gem_dev_set_domain(obj->dev);
3645+
3646+ if (flush_domains & ~(I915_GEM_DOMAIN_CPU|I915_GEM_DOMAIN_GTT))
3647+ (void) i915_add_request(dev, flush_domains);
3648+
3649+ return 0;
3650+}
3651+
3652+/** Unbinds all objects that are on the given buffer list. */
3653+static int
3654+i915_gem_evict_from_list(struct drm_device *dev, struct list_head *head)
3655+{
3656+ struct drm_gem_object *obj;
3657+ struct drm_i915_gem_object *obj_priv;
3658+ int ret;
3659+
3660+ while (!list_empty(head)) {
3661+ obj_priv = list_first_entry(head,
3662+ struct drm_i915_gem_object,
3663+ list);
3664+ obj = obj_priv->obj;
3665+
3666+ if (obj_priv->pin_count != 0) {
3667+ DRM_ERROR("Pinned object in unbind list\n");
3668+ mutex_unlock(&dev->struct_mutex);
3669+ return -EINVAL;
3670+ }
3671+
3672+ ret = i915_gem_object_unbind(obj);
3673+ if (ret != 0) {
3674+ DRM_ERROR("Error unbinding object in LeaveVT: %d\n",
3675+ ret);
3676+ mutex_unlock(&dev->struct_mutex);
3677+ return ret;
3678+ }
3679+ }
3680+
3681+
3682+ return 0;
3683+}
3684+
3685+static int
3686+i915_gem_idle(struct drm_device *dev)
3687+{
3688+ drm_i915_private_t *dev_priv = dev->dev_private;
3689+ uint32_t seqno, cur_seqno, last_seqno;
3690+ int stuck;
3691+
3692+ if (dev_priv->mm.suspended)
3693+ return 0;
3694+
3695+ /* Hack! Don't let anybody do execbuf while we don't control the chip.
3696+ * We need to replace this with a semaphore, or something.
3697+ */
3698+ dev_priv->mm.suspended = 1;
3699+
3700+ i915_kernel_lost_context(dev);
3701+
3702+ /* Flush the GPU along with all non-CPU write domains
3703+ */
3704+ i915_gem_flush(dev, ~(I915_GEM_DOMAIN_CPU|I915_GEM_DOMAIN_GTT),
3705+ ~(I915_GEM_DOMAIN_CPU|I915_GEM_DOMAIN_GTT));
3706+ seqno = i915_add_request(dev, ~(I915_GEM_DOMAIN_CPU |
3707+ I915_GEM_DOMAIN_GTT));
3708+
3709+ if (seqno == 0) {
3710+ mutex_unlock(&dev->struct_mutex);
3711+ return -ENOMEM;
3712+ }
3713+
3714+ dev_priv->mm.waiting_gem_seqno = seqno;
3715+ last_seqno = 0;
3716+ stuck = 0;
3717+ for (;;) {
3718+ cur_seqno = i915_get_gem_seqno(dev);
3719+ if (i915_seqno_passed(cur_seqno, seqno))
3720+ break;
3721+ if (last_seqno == cur_seqno) {
3722+ if (stuck++ > 100) {
3723+ DRM_ERROR("hardware wedged\n");
3724+ dev_priv->mm.wedged = 1;
3725+ DRM_WAKEUP(&dev_priv->irq_queue);
3726+ break;
3727+ }
3728+ }
3729+ msleep(10);
3730+ last_seqno = cur_seqno;
3731+ }
3732+ dev_priv->mm.waiting_gem_seqno = 0;
3733+
3734+ i915_gem_retire_requests(dev);
3735+
3736+ /* Active and flushing should now be empty as we've
3737+ * waited for a sequence higher than any pending execbuffer
3738+ */
3739+ BUG_ON(!list_empty(&dev_priv->mm.active_list));
3740+ BUG_ON(!list_empty(&dev_priv->mm.flushing_list));
3741+
3742+ /* Request should now be empty as we've also waited
3743+ * for the last request in the list
3744+ */
3745+ BUG_ON(!list_empty(&dev_priv->mm.request_list));
3746+
3747+ /* Move all buffers out of the GTT. */
3748+ i915_gem_evict_from_list(dev, &dev_priv->mm.inactive_list);
3749+
3750+ BUG_ON(!list_empty(&dev_priv->mm.active_list));
3751+ BUG_ON(!list_empty(&dev_priv->mm.flushing_list));
3752+ BUG_ON(!list_empty(&dev_priv->mm.inactive_list));
3753+ BUG_ON(!list_empty(&dev_priv->mm.request_list));
3754+ return 0;
3755+}
3756+
3757+static int
3758+i915_gem_init_hws(struct drm_device *dev)
3759+{
3760+ drm_i915_private_t *dev_priv = dev->dev_private;
3761+ struct drm_gem_object *obj;
3762+ struct drm_i915_gem_object *obj_priv;
3763+ int ret;
3764+
3765+ /* If we need a physical address for the status page, it's already
3766+ * initialized at driver load time.
3767+ */
3768+ if (!I915_NEED_GFX_HWS(dev))
3769+ return 0;
3770+
3771+ obj = drm_gem_object_alloc(dev, 4096);
3772+ if (obj == NULL) {
3773+ DRM_ERROR("Failed to allocate status page\n");
3774+ return -ENOMEM;
3775+ }
3776+ obj_priv = obj->driver_private;
3777+
3778+ ret = i915_gem_object_pin(obj, 4096);
3779+ if (ret != 0) {
3780+ drm_gem_object_unreference(obj);
3781+ return ret;
3782+ }
3783+
3784+ dev_priv->status_gfx_addr = obj_priv->gtt_offset;
3785+ dev_priv->hws_map.offset = dev->agp->base + obj_priv->gtt_offset;
3786+ dev_priv->hws_map.size = 4096;
3787+ dev_priv->hws_map.type = 0;
3788+ dev_priv->hws_map.flags = 0;
3789+ dev_priv->hws_map.mtrr = 0;
3790+
3791+ drm_core_ioremap(&dev_priv->hws_map, dev);
3792+ if (dev_priv->hws_map.handle == NULL) {
3793+ DRM_ERROR("Failed to map status page.\n");
3794+ memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map));
3795+ drm_gem_object_unreference(obj);
3796+ return -EINVAL;
3797+ }
3798+ dev_priv->hws_obj = obj;
3799+ dev_priv->hw_status_page = dev_priv->hws_map.handle;
3800+ memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
3801+ I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr);
3802+ DRM_DEBUG("hws offset: 0x%08x\n", dev_priv->status_gfx_addr);
3803+
3804+ return 0;
3805+}
3806+
3807+static int
3808+i915_gem_init_ringbuffer(struct drm_device *dev)
3809+{
3810+ drm_i915_private_t *dev_priv = dev->dev_private;
3811+ struct drm_gem_object *obj;
3812+ struct drm_i915_gem_object *obj_priv;
3813+ int ret;
3814+
3815+ ret = i915_gem_init_hws(dev);
3816+ if (ret != 0)
3817+ return ret;
3818+
3819+ obj = drm_gem_object_alloc(dev, 128 * 1024);
3820+ if (obj == NULL) {
3821+ DRM_ERROR("Failed to allocate ringbuffer\n");
3822+ return -ENOMEM;
3823+ }
3824+ obj_priv = obj->driver_private;
3825+
3826+ ret = i915_gem_object_pin(obj, 4096);
3827+ if (ret != 0) {
3828+ drm_gem_object_unreference(obj);
3829+ return ret;
3830+ }
3831+
3832+ /* Set up the kernel mapping for the ring. */
3833+ dev_priv->ring.Size = obj->size;
3834+ dev_priv->ring.tail_mask = obj->size - 1;
3835+
3836+ dev_priv->ring.map.offset = dev->agp->base + obj_priv->gtt_offset;
3837+ dev_priv->ring.map.size = obj->size;
3838+ dev_priv->ring.map.type = 0;
3839+ dev_priv->ring.map.flags = 0;
3840+ dev_priv->ring.map.mtrr = 0;
3841+
3842+ drm_core_ioremap(&dev_priv->ring.map, dev);
3843+ if (dev_priv->ring.map.handle == NULL) {
3844+ DRM_ERROR("Failed to map ringbuffer.\n");
3845+ memset(&dev_priv->ring, 0, sizeof(dev_priv->ring));
3846+ drm_gem_object_unreference(obj);
3847+ return -EINVAL;
3848+ }
3849+ dev_priv->ring.ring_obj = obj;
3850+ dev_priv->ring.virtual_start = dev_priv->ring.map.handle;
3851+
3852+ /* Stop the ring if it's running. */
3853+ I915_WRITE(PRB0_CTL, 0);
3854+ I915_WRITE(PRB0_HEAD, 0);
3855+ I915_WRITE(PRB0_TAIL, 0);
3856+ I915_WRITE(PRB0_START, 0);
3857+
3858+ /* Initialize the ring. */
3859+ I915_WRITE(PRB0_START, obj_priv->gtt_offset);
3860+ I915_WRITE(PRB0_CTL,
3861+ ((obj->size - 4096) & RING_NR_PAGES) |
3862+ RING_NO_REPORT |
3863+ RING_VALID);
3864+
3865+ /* Update our cache of the ring state */
3866+ i915_kernel_lost_context(dev);
3867+
3868+ return 0;
3869+}
3870+
3871+static void
3872+i915_gem_cleanup_ringbuffer(struct drm_device *dev)
3873+{
3874+ drm_i915_private_t *dev_priv = dev->dev_private;
3875+
3876+ if (dev_priv->ring.ring_obj == NULL)
3877+ return;
3878+
3879+ drm_core_ioremapfree(&dev_priv->ring.map, dev);
3880+
3881+ i915_gem_object_unpin(dev_priv->ring.ring_obj);
3882+ drm_gem_object_unreference(dev_priv->ring.ring_obj);
3883+ dev_priv->ring.ring_obj = NULL;
3884+ memset(&dev_priv->ring, 0, sizeof(dev_priv->ring));
3885+
3886+ if (dev_priv->hws_obj != NULL) {
3887+ i915_gem_object_unpin(dev_priv->hws_obj);
3888+ drm_gem_object_unreference(dev_priv->hws_obj);
3889+ dev_priv->hws_obj = NULL;
3890+ memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map));
3891+
3892+ /* Write high address into HWS_PGA when disabling. */
3893+ I915_WRITE(HWS_PGA, 0x1ffff000);
3894+ }
3895+}
3896+
3897+int
3898+i915_gem_entervt_ioctl(struct drm_device *dev, void *data,
3899+ struct drm_file *file_priv)
3900+{
3901+ drm_i915_private_t *dev_priv = dev->dev_private;
3902+ int ret;
3903+
3904+ if (dev_priv->mm.wedged) {
3905+ DRM_ERROR("Reenabling wedged hardware, good luck\n");
3906+ dev_priv->mm.wedged = 0;
3907+ }
3908+
3909+ ret = i915_gem_init_ringbuffer(dev);
3910+ if (ret != 0)
3911+ return ret;
3912+
3913+ mutex_lock(&dev->struct_mutex);
3914+ BUG_ON(!list_empty(&dev_priv->mm.active_list));
3915+ BUG_ON(!list_empty(&dev_priv->mm.flushing_list));
3916+ BUG_ON(!list_empty(&dev_priv->mm.inactive_list));
3917+ BUG_ON(!list_empty(&dev_priv->mm.request_list));
3918+ dev_priv->mm.suspended = 0;
3919+ mutex_unlock(&dev->struct_mutex);
3920+ return 0;
3921+}
3922+
3923+int
3924+i915_gem_leavevt_ioctl(struct drm_device *dev, void *data,
3925+ struct drm_file *file_priv)
3926+{
3927+ int ret;
3928+
3929+ mutex_lock(&dev->struct_mutex);
3930+ ret = i915_gem_idle(dev);
3931+ if (ret == 0)
3932+ i915_gem_cleanup_ringbuffer(dev);
3933+ mutex_unlock(&dev->struct_mutex);
3934+
3935+ return 0;
3936+}
3937+
3938+void
3939+i915_gem_lastclose(struct drm_device *dev)
3940+{
3941+ int ret;
3942+ drm_i915_private_t *dev_priv = dev->dev_private;
3943+
3944+ mutex_lock(&dev->struct_mutex);
3945+
3946+ if (dev_priv->ring.ring_obj != NULL) {
3947+ ret = i915_gem_idle(dev);
3948+ if (ret)
3949+ DRM_ERROR("failed to idle hardware: %d\n", ret);
3950+
3951+ i915_gem_cleanup_ringbuffer(dev);
3952+ }
3953+
3954+ mutex_unlock(&dev->struct_mutex);
3955+}
3956+
3957+void
3958+i915_gem_load(struct drm_device *dev)
3959+{
3960+ drm_i915_private_t *dev_priv = dev->dev_private;
3961+
3962+ INIT_LIST_HEAD(&dev_priv->mm.active_list);
3963+ INIT_LIST_HEAD(&dev_priv->mm.flushing_list);
3964+ INIT_LIST_HEAD(&dev_priv->mm.inactive_list);
3965+ INIT_LIST_HEAD(&dev_priv->mm.request_list);
3966+ INIT_DELAYED_WORK(&dev_priv->mm.retire_work,
3967+ i915_gem_retire_work_handler);
3968+ dev_priv->mm.next_gem_seqno = 1;
3969+
3970+ i915_gem_detect_bit_6_swizzle(dev);
3971+}
3972--- /dev/null
3973+++ b/drivers/gpu/drm/i915/i915_gem_debug.c
3974@@ -0,0 +1,201 @@
3975+/*
3976+ * Copyright © 2008 Intel Corporation
3977+ *
3978+ * Permission is hereby granted, free of charge, to any person obtaining a
3979+ * copy of this software and associated documentation files (the "Software"),
3980+ * to deal in the Software without restriction, including without limitation
3981+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
3982+ * and/or sell copies of the Software, and to permit persons to whom the
3983+ * Software is furnished to do so, subject to the following conditions:
3984+ *
3985+ * The above copyright notice and this permission notice (including the next
3986+ * paragraph) shall be included in all copies or substantial portions of the
3987+ * Software.
3988+ *
3989+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
3990+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
3991+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
3992+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
3993+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
3994+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
3995+ * IN THE SOFTWARE.
3996+ *
3997+ * Authors:
3998+ * Keith Packard <keithp@keithp.com>
3999+ *
4000+ */
4001+
4002+#include "drmP.h"
4003+#include "drm.h"
4004+#include "i915_drm.h"
4005+#include "i915_drv.h"
4006+
4007+#if WATCH_INACTIVE
4008+void
4009+i915_verify_inactive(struct drm_device *dev, char *file, int line)
4010+{
4011+ drm_i915_private_t *dev_priv = dev->dev_private;
4012+ struct drm_gem_object *obj;
4013+ struct drm_i915_gem_object *obj_priv;
4014+
4015+ list_for_each_entry(obj_priv, &dev_priv->mm.inactive_list, list) {
4016+ obj = obj_priv->obj;
4017+ if (obj_priv->pin_count || obj_priv->active ||
4018+ (obj->write_domain & ~(I915_GEM_DOMAIN_CPU |
4019+ I915_GEM_DOMAIN_GTT)))
4020+ DRM_ERROR("inactive %p (p %d a %d w %x) %s:%d\n",
4021+ obj,
4022+ obj_priv->pin_count, obj_priv->active,
4023+ obj->write_domain, file, line);
4024+ }
4025+}
4026+#endif /* WATCH_INACTIVE */
4027+
4028+
4029+#if WATCH_BUF | WATCH_EXEC | WATCH_PWRITE
4030+static void
4031+i915_gem_dump_page(struct page *page, uint32_t start, uint32_t end,
4032+ uint32_t bias, uint32_t mark)
4033+{
4034+ uint32_t *mem = kmap_atomic(page, KM_USER0);
4035+ int i;
4036+ for (i = start; i < end; i += 4)
4037+ DRM_INFO("%08x: %08x%s\n",
4038+ (int) (bias + i), mem[i / 4],
4039+ (bias + i == mark) ? " ********" : "");
4040+ kunmap_atomic(mem, KM_USER0);
4041+ /* give syslog time to catch up */
4042+ msleep(1);
4043+}
4044+
4045+void
4046+i915_gem_dump_object(struct drm_gem_object *obj, int len,
4047+ const char *where, uint32_t mark)
4048+{
4049+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
4050+ int page;
4051+
4052+ DRM_INFO("%s: object at offset %08x\n", where, obj_priv->gtt_offset);
4053+ for (page = 0; page < (len + PAGE_SIZE-1) / PAGE_SIZE; page++) {
4054+ int page_len, chunk, chunk_len;
4055+
4056+ page_len = len - page * PAGE_SIZE;
4057+ if (page_len > PAGE_SIZE)
4058+ page_len = PAGE_SIZE;
4059+
4060+ for (chunk = 0; chunk < page_len; chunk += 128) {
4061+ chunk_len = page_len - chunk;
4062+ if (chunk_len > 128)
4063+ chunk_len = 128;
4064+ i915_gem_dump_page(obj_priv->page_list[page],
4065+ chunk, chunk + chunk_len,
4066+ obj_priv->gtt_offset +
4067+ page * PAGE_SIZE,
4068+ mark);
4069+ }
4070+ }
4071+}
4072+#endif
4073+
4074+#if WATCH_LRU
4075+void
4076+i915_dump_lru(struct drm_device *dev, const char *where)
4077+{
4078+ drm_i915_private_t *dev_priv = dev->dev_private;
4079+ struct drm_i915_gem_object *obj_priv;
4080+
4081+ DRM_INFO("active list %s {\n", where);
4082+ list_for_each_entry(obj_priv, &dev_priv->mm.active_list,
4083+ list)
4084+ {
4085+ DRM_INFO(" %p: %08x\n", obj_priv,
4086+ obj_priv->last_rendering_seqno);
4087+ }
4088+ DRM_INFO("}\n");
4089+ DRM_INFO("flushing list %s {\n", where);
4090+ list_for_each_entry(obj_priv, &dev_priv->mm.flushing_list,
4091+ list)
4092+ {
4093+ DRM_INFO(" %p: %08x\n", obj_priv,
4094+ obj_priv->last_rendering_seqno);
4095+ }
4096+ DRM_INFO("}\n");
4097+ DRM_INFO("inactive %s {\n", where);
4098+ list_for_each_entry(obj_priv, &dev_priv->mm.inactive_list, list) {
4099+ DRM_INFO(" %p: %08x\n", obj_priv,
4100+ obj_priv->last_rendering_seqno);
4101+ }
4102+ DRM_INFO("}\n");
4103+}
4104+#endif
4105+
4106+
4107+#if WATCH_COHERENCY
4108+void
4109+i915_gem_object_check_coherency(struct drm_gem_object *obj, int handle)
4110+{
4111+ struct drm_device *dev = obj->dev;
4112+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
4113+ int page;
4114+ uint32_t *gtt_mapping;
4115+ uint32_t *backing_map = NULL;
4116+ int bad_count = 0;
4117+
4118+ DRM_INFO("%s: checking coherency of object %p@0x%08x (%d, %dkb):\n",
4119+ __func__, obj, obj_priv->gtt_offset, handle,
4120+ obj->size / 1024);
4121+
4122+ gtt_mapping = ioremap(dev->agp->base + obj_priv->gtt_offset,
4123+ obj->size);
4124+ if (gtt_mapping == NULL) {
4125+ DRM_ERROR("failed to map GTT space\n");
4126+ return;
4127+ }
4128+
4129+ for (page = 0; page < obj->size / PAGE_SIZE; page++) {
4130+ int i;
4131+
4132+ backing_map = kmap_atomic(obj_priv->page_list[page], KM_USER0);
4133+
4134+ if (backing_map == NULL) {
4135+ DRM_ERROR("failed to map backing page\n");
4136+ goto out;
4137+ }
4138+
4139+ for (i = 0; i < PAGE_SIZE / 4; i++) {
4140+ uint32_t cpuval = backing_map[i];
4141+ uint32_t gttval = readl(gtt_mapping +
4142+ page * 1024 + i);
4143+
4144+ if (cpuval != gttval) {
4145+ DRM_INFO("incoherent CPU vs GPU at 0x%08x: "
4146+ "0x%08x vs 0x%08x\n",
4147+ (int)(obj_priv->gtt_offset +
4148+ page * PAGE_SIZE + i * 4),
4149+ cpuval, gttval);
4150+ if (bad_count++ >= 8) {
4151+ DRM_INFO("...\n");
4152+ goto out;
4153+ }
4154+ }
4155+ }
4156+ kunmap_atomic(backing_map, KM_USER0);
4157+ backing_map = NULL;
4158+ }
4159+
4160+ out:
4161+ if (backing_map != NULL)
4162+ kunmap_atomic(backing_map, KM_USER0);
4163+ iounmap(gtt_mapping);
4164+
4165+ /* give syslog time to catch up */
4166+ msleep(1);
4167+
4168+ /* Directly flush the object, since we just loaded values with the CPU
4169+ * from the backing pages and we don't want to disturb the cache
4170+ * management that we're trying to observe.
4171+ */
4172+
4173+ i915_gem_clflush_object(obj);
4174+}
4175+#endif
4176--- /dev/null
4177+++ b/drivers/gpu/drm/i915/i915_gem_proc.c
4178@@ -0,0 +1,292 @@
4179+/*
4180+ * Copyright © 2008 Intel Corporation
4181+ *
4182+ * Permission is hereby granted, free of charge, to any person obtaining a
4183+ * copy of this software and associated documentation files (the "Software"),
4184+ * to deal in the Software without restriction, including without limitation
4185+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
4186+ * and/or sell copies of the Software, and to permit persons to whom the
4187+ * Software is furnished to do so, subject to the following conditions:
4188+ *
4189+ * The above copyright notice and this permission notice (including the next
4190+ * paragraph) shall be included in all copies or substantial portions of the
4191+ * Software.
4192+ *
4193+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
4194+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
4195+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
4196+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
4197+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
4198+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
4199+ * IN THE SOFTWARE.
4200+ *
4201+ * Authors:
4202+ * Eric Anholt <eric@anholt.net>
4203+ * Keith Packard <keithp@keithp.com>
4204+ *
4205+ */
4206+
4207+#include "drmP.h"
4208+#include "drm.h"
4209+#include "i915_drm.h"
4210+#include "i915_drv.h"
4211+
4212+static int i915_gem_active_info(char *buf, char **start, off_t offset,
4213+ int request, int *eof, void *data)
4214+{
4215+ struct drm_minor *minor = (struct drm_minor *) data;
4216+ struct drm_device *dev = minor->dev;
4217+ drm_i915_private_t *dev_priv = dev->dev_private;
4218+ struct drm_i915_gem_object *obj_priv;
4219+ int len = 0;
4220+
4221+ if (offset > DRM_PROC_LIMIT) {
4222+ *eof = 1;
4223+ return 0;
4224+ }
4225+
4226+ *start = &buf[offset];
4227+ *eof = 0;
4228+ DRM_PROC_PRINT("Active:\n");
4229+ list_for_each_entry(obj_priv, &dev_priv->mm.active_list,
4230+ list)
4231+ {
4232+ struct drm_gem_object *obj = obj_priv->obj;
4233+ if (obj->name) {
4234+ DRM_PROC_PRINT(" %p(%d): %08x %08x %d\n",
4235+ obj, obj->name,
4236+ obj->read_domains, obj->write_domain,
4237+ obj_priv->last_rendering_seqno);
4238+ } else {
4239+ DRM_PROC_PRINT(" %p: %08x %08x %d\n",
4240+ obj,
4241+ obj->read_domains, obj->write_domain,
4242+ obj_priv->last_rendering_seqno);
4243+ }
4244+ }
4245+ if (len > request + offset)
4246+ return request;
4247+ *eof = 1;
4248+ return len - offset;
4249+}
4250+
4251+static int i915_gem_flushing_info(char *buf, char **start, off_t offset,
4252+ int request, int *eof, void *data)
4253+{
4254+ struct drm_minor *minor = (struct drm_minor *) data;
4255+ struct drm_device *dev = minor->dev;
4256+ drm_i915_private_t *dev_priv = dev->dev_private;
4257+ struct drm_i915_gem_object *obj_priv;
4258+ int len = 0;
4259+
4260+ if (offset > DRM_PROC_LIMIT) {
4261+ *eof = 1;
4262+ return 0;
4263+ }
4264+
4265+ *start = &buf[offset];
4266+ *eof = 0;
4267+ DRM_PROC_PRINT("Flushing:\n");
4268+ list_for_each_entry(obj_priv, &dev_priv->mm.flushing_list,
4269+ list)
4270+ {
4271+ struct drm_gem_object *obj = obj_priv->obj;
4272+ if (obj->name) {
4273+ DRM_PROC_PRINT(" %p(%d): %08x %08x %d\n",
4274+ obj, obj->name,
4275+ obj->read_domains, obj->write_domain,
4276+ obj_priv->last_rendering_seqno);
4277+ } else {
4278+ DRM_PROC_PRINT(" %p: %08x %08x %d\n", obj,
4279+ obj->read_domains, obj->write_domain,
4280+ obj_priv->last_rendering_seqno);
4281+ }
4282+ }
4283+ if (len > request + offset)
4284+ return request;
4285+ *eof = 1;
4286+ return len - offset;
4287+}
4288+
4289+static int i915_gem_inactive_info(char *buf, char **start, off_t offset,
4290+ int request, int *eof, void *data)
4291+{
4292+ struct drm_minor *minor = (struct drm_minor *) data;
4293+ struct drm_device *dev = minor->dev;
4294+ drm_i915_private_t *dev_priv = dev->dev_private;
4295+ struct drm_i915_gem_object *obj_priv;
4296+ int len = 0;
4297+
4298+ if (offset > DRM_PROC_LIMIT) {
4299+ *eof = 1;
4300+ return 0;
4301+ }
4302+
4303+ *start = &buf[offset];
4304+ *eof = 0;
4305+ DRM_PROC_PRINT("Inactive:\n");
4306+ list_for_each_entry(obj_priv, &dev_priv->mm.inactive_list,
4307+ list)
4308+ {
4309+ struct drm_gem_object *obj = obj_priv->obj;
4310+ if (obj->name) {
4311+ DRM_PROC_PRINT(" %p(%d): %08x %08x %d\n",
4312+ obj, obj->name,
4313+ obj->read_domains, obj->write_domain,
4314+ obj_priv->last_rendering_seqno);
4315+ } else {
4316+ DRM_PROC_PRINT(" %p: %08x %08x %d\n", obj,
4317+ obj->read_domains, obj->write_domain,
4318+ obj_priv->last_rendering_seqno);
4319+ }
4320+ }
4321+ if (len > request + offset)
4322+ return request;
4323+ *eof = 1;
4324+ return len - offset;
4325+}
4326+
4327+static int i915_gem_request_info(char *buf, char **start, off_t offset,
4328+ int request, int *eof, void *data)
4329+{
4330+ struct drm_minor *minor = (struct drm_minor *) data;
4331+ struct drm_device *dev = minor->dev;
4332+ drm_i915_private_t *dev_priv = dev->dev_private;
4333+ struct drm_i915_gem_request *gem_request;
4334+ int len = 0;
4335+
4336+ if (offset > DRM_PROC_LIMIT) {
4337+ *eof = 1;
4338+ return 0;
4339+ }
4340+
4341+ *start = &buf[offset];
4342+ *eof = 0;
4343+ DRM_PROC_PRINT("Request:\n");
4344+ list_for_each_entry(gem_request, &dev_priv->mm.request_list,
4345+ list)
4346+ {
4347+ DRM_PROC_PRINT(" %d @ %d %08x\n",
4348+ gem_request->seqno,
4349+ (int) (jiffies - gem_request->emitted_jiffies),
4350+ gem_request->flush_domains);
4351+ }
4352+ if (len > request + offset)
4353+ return request;
4354+ *eof = 1;
4355+ return len - offset;
4356+}
4357+
4358+static int i915_gem_seqno_info(char *buf, char **start, off_t offset,
4359+ int request, int *eof, void *data)
4360+{
4361+ struct drm_minor *minor = (struct drm_minor *) data;
4362+ struct drm_device *dev = minor->dev;
4363+ drm_i915_private_t *dev_priv = dev->dev_private;
4364+ int len = 0;
4365+
4366+ if (offset > DRM_PROC_LIMIT) {
4367+ *eof = 1;
4368+ return 0;
4369+ }
4370+
4371+ *start = &buf[offset];
4372+ *eof = 0;
4373+ DRM_PROC_PRINT("Current sequence: %d\n", i915_get_gem_seqno(dev));
4374+ DRM_PROC_PRINT("Waiter sequence: %d\n",
4375+ dev_priv->mm.waiting_gem_seqno);
4376+ DRM_PROC_PRINT("IRQ sequence: %d\n", dev_priv->mm.irq_gem_seqno);
4377+ if (len > request + offset)
4378+ return request;
4379+ *eof = 1;
4380+ return len - offset;
4381+}
4382+
4383+
4384+static int i915_interrupt_info(char *buf, char **start, off_t offset,
4385+ int request, int *eof, void *data)
4386+{
4387+ struct drm_minor *minor = (struct drm_minor *) data;
4388+ struct drm_device *dev = minor->dev;
4389+ drm_i915_private_t *dev_priv = dev->dev_private;
4390+ int len = 0;
4391+
4392+ if (offset > DRM_PROC_LIMIT) {
4393+ *eof = 1;
4394+ return 0;
4395+ }
4396+
4397+ *start = &buf[offset];
4398+ *eof = 0;
4399+ DRM_PROC_PRINT("Interrupt enable: %08x\n",
4400+ I915_READ(IER));
4401+ DRM_PROC_PRINT("Interrupt identity: %08x\n",
4402+ I915_READ(IIR));
4403+ DRM_PROC_PRINT("Interrupt mask: %08x\n",
4404+ I915_READ(IMR));
4405+ DRM_PROC_PRINT("Pipe A stat: %08x\n",
4406+ I915_READ(PIPEASTAT));
4407+ DRM_PROC_PRINT("Pipe B stat: %08x\n",
4408+ I915_READ(PIPEBSTAT));
4409+ DRM_PROC_PRINT("Interrupts received: %d\n",
4410+ atomic_read(&dev_priv->irq_received));
4411+ DRM_PROC_PRINT("Current sequence: %d\n",
4412+ i915_get_gem_seqno(dev));
4413+ DRM_PROC_PRINT("Waiter sequence: %d\n",
4414+ dev_priv->mm.waiting_gem_seqno);
4415+ DRM_PROC_PRINT("IRQ sequence: %d\n",
4416+ dev_priv->mm.irq_gem_seqno);
4417+ if (len > request + offset)
4418+ return request;
4419+ *eof = 1;
4420+ return len - offset;
4421+}
4422+
4423+static struct drm_proc_list {
4424+ /** file name */
4425+ const char *name;
4426+ /** proc callback*/
4427+ int (*f) (char *, char **, off_t, int, int *, void *);
4428+} i915_gem_proc_list[] = {
4429+ {"i915_gem_active", i915_gem_active_info},
4430+ {"i915_gem_flushing", i915_gem_flushing_info},
4431+ {"i915_gem_inactive", i915_gem_inactive_info},
4432+ {"i915_gem_request", i915_gem_request_info},
4433+ {"i915_gem_seqno", i915_gem_seqno_info},
4434+ {"i915_gem_interrupt", i915_interrupt_info},
4435+};
4436+
4437+#define I915_GEM_PROC_ENTRIES ARRAY_SIZE(i915_gem_proc_list)
4438+
4439+int i915_gem_proc_init(struct drm_minor *minor)
4440+{
4441+ struct proc_dir_entry *ent;
4442+ int i, j;
4443+
4444+ for (i = 0; i < I915_GEM_PROC_ENTRIES; i++) {
4445+ ent = create_proc_entry(i915_gem_proc_list[i].name,
4446+ S_IFREG | S_IRUGO, minor->dev_root);
4447+ if (!ent) {
4448+ DRM_ERROR("Cannot create /proc/dri/.../%s\n",
4449+ i915_gem_proc_list[i].name);
4450+ for (j = 0; j < i; j++)
4451+ remove_proc_entry(i915_gem_proc_list[i].name,
4452+ minor->dev_root);
4453+ return -1;
4454+ }
4455+ ent->read_proc = i915_gem_proc_list[i].f;
4456+ ent->data = minor;
4457+ }
4458+ return 0;
4459+}
4460+
4461+void i915_gem_proc_cleanup(struct drm_minor *minor)
4462+{
4463+ int i;
4464+
4465+ if (!minor->dev_root)
4466+ return;
4467+
4468+ for (i = 0; i < I915_GEM_PROC_ENTRIES; i++)
4469+ remove_proc_entry(i915_gem_proc_list[i].name, minor->dev_root);
4470+}
4471--- /dev/null
4472+++ b/drivers/gpu/drm/i915/i915_gem_tiling.c
4473@@ -0,0 +1,271 @@
4474+/*
4475+ * Copyright © 2008 Intel Corporation
4476+ *
4477+ * Permission is hereby granted, free of charge, to any person obtaining a
4478+ * copy of this software and associated documentation files (the "Software"),
4479+ * to deal in the Software without restriction, including without limitation
4480+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
4481+ * and/or sell copies of the Software, and to permit persons to whom the
4482+ * Software is furnished to do so, subject to the following conditions:
4483+ *
4484+ * The above copyright notice and this permission notice (including the next
4485+ * paragraph) shall be included in all copies or substantial portions of the
4486+ * Software.
4487+ *
4488+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
4489+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
4490+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
4491+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
4492+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
4493+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
4494+ * IN THE SOFTWARE.
4495+ *
4496+ * Authors:
4497+ * Eric Anholt <eric@anholt.net>
4498+ *
4499+ */
4500+
4501+#include "drmP.h"
4502+#include "drm.h"
4503+#include "i915_drm.h"
4504+#include "i915_drv.h"
4505+
4506+/** @file i915_gem_tiling.c
4507+ *
4508+ * Support for managing tiling state of buffer objects.
4509+ *
4510+ * The idea behind tiling is to increase cache hit rates by rearranging
4511+ * pixel data so that a group of pixel accesses are in the same cacheline.
4512+ * Performance improvement from doing this on the back/depth buffer are on
4513+ * the order of 30%.
4514+ *
4515+ * Intel architectures make this somewhat more complicated, though, by
4516+ * adjustments made to addressing of data when the memory is in interleaved
4517+ * mode (matched pairs of DIMMS) to improve memory bandwidth.
4518+ * For interleaved memory, the CPU sends every sequential 64 bytes
4519+ * to an alternate memory channel so it can get the bandwidth from both.
4520+ *
4521+ * The GPU also rearranges its accesses for increased bandwidth to interleaved
4522+ * memory, and it matches what the CPU does for non-tiled. However, when tiled
4523+ * it does it a little differently, since one walks addresses not just in the
4524+ * X direction but also Y. So, along with alternating channels when bit
4525+ * 6 of the address flips, it also alternates when other bits flip -- Bits 9
4526+ * (every 512 bytes, an X tile scanline) and 10 (every two X tile scanlines)
4527+ * are common to both the 915 and 965-class hardware.
4528+ *
4529+ * The CPU also sometimes XORs in higher bits as well, to improve
4530+ * bandwidth doing strided access like we do so frequently in graphics. This
4531+ * is called "Channel XOR Randomization" in the MCH documentation. The result
4532+ * is that the CPU is XORing in either bit 11 or bit 17 to bit 6 of its address
4533+ * decode.
4534+ *
4535+ * All of this bit 6 XORing has an effect on our memory management,
4536+ * as we need to make sure that the 3d driver can correctly address object
4537+ * contents.
4538+ *
4539+ * If we don't have interleaved memory, all tiling is safe and no swizzling is
4540+ * required.
4541+ *
4542+ * When bit 17 is XORed in, we simply refuse to tile at all. Bit
4543+ * 17 is not just a page offset, so as we page an objet out and back in,
4544+ * individual pages in it will have different bit 17 addresses, resulting in
4545+ * each 64 bytes being swapped with its neighbor!
4546+ *
4547+ * Otherwise, if interleaved, we have to tell the 3d driver what the address
4548+ * swizzling it needs to do is, since it's writing with the CPU to the pages
4549+ * (bit 6 and potentially bit 11 XORed in), and the GPU is reading from the
4550+ * pages (bit 6, 9, and 10 XORed in), resulting in a cumulative bit swizzling
4551+ * required by the CPU of XORing in bit 6, 9, 10, and potentially 11, in order
4552+ * to match what the GPU expects.
4553+ */
4554+
4555+/**
4556+ * Detects bit 6 swizzling of address lookup between IGD access and CPU
4557+ * access through main memory.
4558+ */
4559+void
4560+i915_gem_detect_bit_6_swizzle(struct drm_device *dev)
4561+{
4562+ drm_i915_private_t *dev_priv = dev->dev_private;
4563+ struct pci_dev *bridge;
4564+ uint32_t swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN;
4565+ uint32_t swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN;
4566+ int ret;
4567+
4568+ if (IS_I965G(dev) && !IS_I965GM(dev)) {
4569+ uint32_t chdecmisc;
4570+
4571+ /* On the 965, channel interleave appears to be determined by
4572+ * the flex bit. If flex is set, then the ranks (sides of a
4573+ * DIMM) of memory will be "stacked" (physical addresses walk
4574+ * through one rank then move on to the next, flipping channels
4575+ * or not depending on rank configuration). The GPU in this
4576+ * case does exactly the same addressing as the CPU.
4577+ *
4578+ * Unlike the 945, channel randomization based does not
4579+ * appear to be available.
4580+ *
4581+ * XXX: While the G965 doesn't appear to do any interleaving
4582+ * when the DIMMs are not exactly matched, the G4x chipsets
4583+ * might be for "L-shaped" configurations, and will need to be
4584+ * detected.
4585+ *
4586+ * L-shaped configuration:
4587+ *
4588+ * +-----+
4589+ * | |
4590+ * |DIMM2| <-- non-interleaved
4591+ * +-----+
4592+ * +-----+ +-----+
4593+ * | | | |
4594+ * |DIMM0| |DIMM1| <-- interleaved area
4595+ * +-----+ +-----+
4596+ */
4597+ chdecmisc = I915_READ(CHDECMISC);
4598+
4599+ if (chdecmisc == 0xff) {
4600+ DRM_ERROR("Couldn't read from MCHBAR. "
4601+ "Disabling tiling.\n");
4602+ } else if (chdecmisc & CHDECMISC_FLEXMEMORY) {
4603+ swizzle_x = I915_BIT_6_SWIZZLE_NONE;
4604+ swizzle_y = I915_BIT_6_SWIZZLE_NONE;
4605+ } else {
4606+ swizzle_x = I915_BIT_6_SWIZZLE_9_10;
4607+ swizzle_y = I915_BIT_6_SWIZZLE_9;
4608+ }
4609+ } else if (IS_I9XX(dev)) {
4610+ uint32_t dcc;
4611+
4612+ /* On 915-945 and GM965, channel interleave by the CPU is
4613+ * determined by DCC. The CPU will alternate based on bit 6
4614+ * in interleaved mode, and the GPU will then also alternate
4615+ * on bit 6, 9, and 10 for X, but the CPU may also optionally
4616+ * alternate based on bit 17 (XOR not disabled and XOR
4617+ * bit == 17).
4618+ */
4619+ dcc = I915_READ(DCC);
4620+ switch (dcc & DCC_ADDRESSING_MODE_MASK) {
4621+ case DCC_ADDRESSING_MODE_SINGLE_CHANNEL:
4622+ case DCC_ADDRESSING_MODE_DUAL_CHANNEL_ASYMMETRIC:
4623+ swizzle_x = I915_BIT_6_SWIZZLE_NONE;
4624+ swizzle_y = I915_BIT_6_SWIZZLE_NONE;
4625+ break;
4626+ case DCC_ADDRESSING_MODE_DUAL_CHANNEL_INTERLEAVED:
4627+ if (IS_I915G(dev) || IS_I915GM(dev) ||
4628+ dcc & DCC_CHANNEL_XOR_DISABLE) {
4629+ swizzle_x = I915_BIT_6_SWIZZLE_9_10;
4630+ swizzle_y = I915_BIT_6_SWIZZLE_9;
4631+ } else if (IS_I965GM(dev)) {
4632+ /* GM965 only does bit 11-based channel
4633+ * randomization
4634+ */
4635+ swizzle_x = I915_BIT_6_SWIZZLE_9_10_11;
4636+ swizzle_y = I915_BIT_6_SWIZZLE_9_11;
4637+ } else {
4638+ /* Bit 17 or perhaps other swizzling */
4639+ swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN;
4640+ swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN;
4641+ }
4642+ break;
4643+ }
4644+ if (dcc == 0xffffffff) {
4645+ DRM_ERROR("Couldn't read from MCHBAR. "
4646+ "Disabling tiling.\n");
4647+ swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN;
4648+ swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN;
4649+ }
4650+ } else {
4651+ /* As far as we know, the 865 doesn't have these bit 6
4652+ * swizzling issues.
4653+ */
4654+ swizzle_x = I915_BIT_6_SWIZZLE_NONE;
4655+ swizzle_y = I915_BIT_6_SWIZZLE_NONE;
4656+ }
4657+
4658+ dev_priv->mm.bit_6_swizzle_x = swizzle_x;
4659+ dev_priv->mm.bit_6_swizzle_y = swizzle_y;
4660+}
4661+
4662+/**
4663+ * Sets the tiling mode of an object, returning the required swizzling of
4664+ * bit 6 of addresses in the object.
4665+ */
4666+int
4667+i915_gem_set_tiling(struct drm_device *dev, void *data,
4668+ struct drm_file *file_priv)
4669+{
4670+ struct drm_i915_gem_set_tiling *args = data;
4671+ drm_i915_private_t *dev_priv = dev->dev_private;
4672+ struct drm_gem_object *obj;
4673+ struct drm_i915_gem_object *obj_priv;
4674+
4675+ obj = drm_gem_object_lookup(dev, file_priv, args->handle);
4676+ if (obj == NULL)
4677+ return -EINVAL;
4678+ obj_priv = obj->driver_private;
4679+
4680+ mutex_lock(&dev->struct_mutex);
4681+
4682+ if (args->tiling_mode == I915_TILING_NONE) {
4683+ obj_priv->tiling_mode = I915_TILING_NONE;
4684+ args->swizzle_mode = I915_BIT_6_SWIZZLE_NONE;
4685+ } else {
4686+ if (args->tiling_mode == I915_TILING_X)
4687+ args->swizzle_mode = dev_priv->mm.bit_6_swizzle_x;
4688+ else
4689+ args->swizzle_mode = dev_priv->mm.bit_6_swizzle_y;
4690+ /* If we can't handle the swizzling, make it untiled. */
4691+ if (args->swizzle_mode == I915_BIT_6_SWIZZLE_UNKNOWN) {
4692+ args->tiling_mode = I915_TILING_NONE;
4693+ args->swizzle_mode = I915_BIT_6_SWIZZLE_NONE;
4694+ }
4695+ }
4696+ obj_priv->tiling_mode = args->tiling_mode;
4697+
4698+ mutex_unlock(&dev->struct_mutex);
4699+
4700+ drm_gem_object_unreference(obj);
4701+
4702+ return 0;
4703+}
4704+
4705+/**
4706+ * Returns the current tiling mode and required bit 6 swizzling for the object.
4707+ */
4708+int
4709+i915_gem_get_tiling(struct drm_device *dev, void *data,
4710+ struct drm_file *file_priv)
4711+{
4712+ struct drm_i915_gem_get_tiling *args = data;
4713+ drm_i915_private_t *dev_priv = dev->dev_private;
4714+ struct drm_gem_object *obj;
4715+ struct drm_i915_gem_object *obj_priv;
4716+
4717+ obj = drm_gem_object_lookup(dev, file_priv, args->handle);
4718+ if (obj == NULL)
4719+ return -EINVAL;
4720+ obj_priv = obj->driver_private;
4721+
4722+ mutex_lock(&dev->struct_mutex);
4723+
4724+ args->tiling_mode = obj_priv->tiling_mode;
4725+ switch (obj_priv->tiling_mode) {
4726+ case I915_TILING_X:
4727+ args->swizzle_mode = dev_priv->mm.bit_6_swizzle_x;
4728+ break;
4729+ case I915_TILING_Y:
4730+ args->swizzle_mode = dev_priv->mm.bit_6_swizzle_y;
4731+ break;
4732+ case I915_TILING_NONE:
4733+ args->swizzle_mode = I915_BIT_6_SWIZZLE_NONE;
4734+ break;
4735+ default:
4736+ DRM_ERROR("unknown tiling mode\n");
4737+ }
4738+
4739+ mutex_unlock(&dev->struct_mutex);
4740+
4741+ drm_gem_object_unreference(obj);
4742+
4743+ return 0;
4744+}
4745--- a/drivers/gpu/drm/i915/i915_irq.c
4746+++ b/drivers/gpu/drm/i915/i915_irq.c
4747@@ -281,8 +281,10 @@ irqreturn_t i915_driver_irq_handler(DRM_
4748
4749 dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
4750
4751- if (iir & I915_USER_INTERRUPT)
4752+ if (iir & I915_USER_INTERRUPT) {
4753+ dev_priv->mm.irq_gem_seqno = i915_get_gem_seqno(dev);
4754 DRM_WAKEUP(&dev_priv->irq_queue);
4755+ }
4756
4757 if (iir & (I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT |
4758 I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT)) {
4759@@ -343,7 +345,7 @@ static int i915_emit_irq(struct drm_devi
4760 return dev_priv->counter;
4761 }
4762
4763-static void i915_user_irq_get(struct drm_device *dev)
4764+void i915_user_irq_get(struct drm_device *dev)
4765 {
4766 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
4767
4768@@ -353,7 +355,7 @@ static void i915_user_irq_get(struct drm
4769 spin_unlock(&dev_priv->user_irq_lock);
4770 }
4771
4772-static void i915_user_irq_put(struct drm_device *dev)
4773+void i915_user_irq_put(struct drm_device *dev)
4774 {
4775 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
4776
4777--- a/drivers/gpu/drm/i915/i915_reg.h
4778+++ b/drivers/gpu/drm/i915/i915_reg.h
4779@@ -25,19 +25,6 @@
4780 #ifndef _I915_REG_H_
4781 #define _I915_REG_H_
4782
4783-/* MCH MMIO space */
4784-/** 915-945 and GM965 MCH register controlling DRAM channel access */
4785-#define DCC 0x200
4786-#define DCC_ADDRESSING_MODE_SINGLE_CHANNEL (0 << 0)
4787-#define DCC_ADDRESSING_MODE_DUAL_CHANNEL_ASYMMETRIC (1 << 0)
4788-#define DCC_ADDRESSING_MODE_DUAL_CHANNEL_INTERLEAVED (2 << 0)
4789-#define DCC_ADDRESSING_MODE_MASK (3 << 0)
4790-#define DCC_CHANNEL_XOR_DISABLE (1 << 10)
4791-
4792-/** 965 MCH register controlling DRAM channel configuration */
4793-#define CHDECMISC 0x111
4794-#define CHDECMISC_FLEXMEMORY (1 << 1)
4795-
4796 /*
4797 * The Bridge device's PCI config space has information about the
4798 * fb aperture size and the amount of pre-reserved memory.
4799@@ -516,6 +503,30 @@
4800 #define PALETTE_A 0x0a000
4801 #define PALETTE_B 0x0a800
4802
4803+/* MCH MMIO space */
4804+
4805+/*
4806+ * MCHBAR mirror.
4807+ *
4808+ * This mirrors the MCHBAR MMIO space whose location is determined by
4809+ * device 0 function 0's pci config register 0x44 or 0x48 and matches it in
4810+ * every way. It is not accessible from the CP register read instructions.
4811+ *
4812+ */
4813+/** 915-945 and GM965 MCH register controlling DRAM channel access */
4814+#define MCHBAR_MIRROR_BASE 0x10000
4815+
4816+#define DCC 0x10200
4817+#define DCC_ADDRESSING_MODE_SINGLE_CHANNEL (0 << 0)
4818+#define DCC_ADDRESSING_MODE_DUAL_CHANNEL_ASYMMETRIC (1 << 0)
4819+#define DCC_ADDRESSING_MODE_DUAL_CHANNEL_INTERLEAVED (2 << 0)
4820+#define DCC_ADDRESSING_MODE_MASK (3 << 0)
4821+#define DCC_CHANNEL_XOR_DISABLE (1 << 10)
4822+
4823+/** 965 MCH register controlling DRAM channel configuration */
4824+#define CHDECMISC 0x10111
4825+#define CHDECMISC_FLEXMEMORY (1 << 1)
4826+
4827 /*
4828 * Overlay regs
4829 */
4830--- a/include/drm/drm.h
4831+++ b/include/drm/drm.h
4832@@ -573,6 +573,34 @@ struct drm_set_version {
4833 int drm_dd_minor;
4834 };
4835
4836+/** DRM_IOCTL_GEM_CLOSE ioctl argument type */
4837+struct drm_gem_close {
4838+ /** Handle of the object to be closed. */
4839+ uint32_t handle;
4840+ uint32_t pad;
4841+};
4842+
4843+/** DRM_IOCTL_GEM_FLINK ioctl argument type */
4844+struct drm_gem_flink {
4845+ /** Handle for the object being named */
4846+ uint32_t handle;
4847+
4848+ /** Returned global name */
4849+ uint32_t name;
4850+};
4851+
4852+/** DRM_IOCTL_GEM_OPEN ioctl argument type */
4853+struct drm_gem_open {
4854+ /** Name of object being opened */
4855+ uint32_t name;
4856+
4857+ /** Returned handle for the object */
4858+ uint32_t handle;
4859+
4860+ /** Returned size of the object */
4861+ uint64_t size;
4862+};
4863+
4864 #define DRM_IOCTL_BASE 'd'
4865 #define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr)
4866 #define DRM_IOR(nr,type) _IOR(DRM_IOCTL_BASE,nr,type)
4867@@ -587,6 +615,9 @@ struct drm_set_version {
4868 #define DRM_IOCTL_GET_CLIENT DRM_IOWR(0x05, struct drm_client)
4869 #define DRM_IOCTL_GET_STATS DRM_IOR( 0x06, struct drm_stats)
4870 #define DRM_IOCTL_SET_VERSION DRM_IOWR(0x07, struct drm_set_version)
4871+#define DRM_IOCTL_GEM_CLOSE DRM_IOW (0x09, struct drm_gem_close)
4872+#define DRM_IOCTL_GEM_FLINK DRM_IOWR(0x0a, struct drm_gem_flink)
4873+#define DRM_IOCTL_GEM_OPEN DRM_IOWR(0x0b, struct drm_gem_open)
4874
4875 #define DRM_IOCTL_SET_UNIQUE DRM_IOW( 0x10, struct drm_unique)
4876 #define DRM_IOCTL_AUTH_MAGIC DRM_IOW( 0x11, struct drm_auth)
4877--- a/include/drm/drmP.h
4878+++ b/include/drm/drmP.h
4879@@ -104,6 +104,7 @@ struct drm_device;
4880 #define DRIVER_DMA_QUEUE 0x200
4881 #define DRIVER_FB_DMA 0x400
4882 #define DRIVER_IRQ_VBL2 0x800
4883+#define DRIVER_GEM 0x1000
4884
4885 /***********************************************************************/
4886 /** \name Begin the DRM... */
4887@@ -387,6 +388,10 @@ struct drm_file {
4888 struct drm_minor *minor;
4889 int remove_auth_on_close;
4890 unsigned long lock_count;
4891+ /** Mapping of mm object handles to object pointers. */
4892+ struct idr object_idr;
4893+ /** Lock for synchronization of access to object_idr. */
4894+ spinlock_t table_lock;
4895 struct file *filp;
4896 void *driver_priv;
4897 };
4898@@ -558,6 +563,56 @@ struct drm_ati_pcigart_info {
4899 };
4900
4901 /**
4902+ * This structure defines the drm_mm memory object, which will be used by the
4903+ * DRM for its buffer objects.
4904+ */
4905+struct drm_gem_object {
4906+ /** Reference count of this object */
4907+ struct kref refcount;
4908+
4909+ /** Handle count of this object. Each handle also holds a reference */
4910+ struct kref handlecount;
4911+
4912+ /** Related drm device */
4913+ struct drm_device *dev;
4914+
4915+ /** File representing the shmem storage */
4916+ struct file *filp;
4917+
4918+ /**
4919+ * Size of the object, in bytes. Immutable over the object's
4920+ * lifetime.
4921+ */
4922+ size_t size;
4923+
4924+ /**
4925+ * Global name for this object, starts at 1. 0 means unnamed.
4926+ * Access is covered by the object_name_lock in the related drm_device
4927+ */
4928+ int name;
4929+
4930+ /**
4931+ * Memory domains. These monitor which caches contain read/write data
4932+ * related to the object. When transitioning from one set of domains
4933+ * to another, the driver is called to ensure that caches are suitably
4934+ * flushed and invalidated
4935+ */
4936+ uint32_t read_domains;
4937+ uint32_t write_domain;
4938+
4939+ /**
4940+ * While validating an exec operation, the
4941+ * new read/write domain values are computed here.
4942+ * They will be transferred to the above values
4943+ * at the point that any cache flushing occurs
4944+ */
4945+ uint32_t pending_read_domains;
4946+ uint32_t pending_write_domain;
4947+
4948+ void *driver_private;
4949+};
4950+
4951+/**
4952 * DRM driver structure. This structure represent the common code for
4953 * a family of cards. There will one drm_device for each card present
4954 * in this family
4955@@ -614,6 +669,18 @@ struct drm_driver {
4956 void (*set_version) (struct drm_device *dev,
4957 struct drm_set_version *sv);
4958
4959+ int (*proc_init)(struct drm_minor *minor);
4960+ void (*proc_cleanup)(struct drm_minor *minor);
4961+
4962+ /**
4963+ * Driver-specific constructor for drm_gem_objects, to set up
4964+ * obj->driver_private.
4965+ *
4966+ * Returns 0 on success.
4967+ */
4968+ int (*gem_init_object) (struct drm_gem_object *obj);
4969+ void (*gem_free_object) (struct drm_gem_object *obj);
4970+
4971 int major;
4972 int minor;
4973 int patchlevel;
4974@@ -771,6 +838,22 @@ struct drm_device {
4975 spinlock_t drw_lock;
4976 struct idr drw_idr;
4977 /*@} */
4978+
4979+ /** \name GEM information */
4980+ /*@{ */
4981+ spinlock_t object_name_lock;
4982+ struct idr object_name_idr;
4983+ atomic_t object_count;
4984+ atomic_t object_memory;
4985+ atomic_t pin_count;
4986+ atomic_t pin_memory;
4987+ atomic_t gtt_count;
4988+ atomic_t gtt_memory;
4989+ uint32_t gtt_total;
4990+ uint32_t invalidate_domains; /* domains pending invalidation */
4991+ uint32_t flush_domains; /* domains pending flush */
4992+ /*@} */
4993+
4994 };
4995
4996 static __inline__ int drm_core_check_feature(struct drm_device *dev,
4997@@ -867,6 +950,10 @@ extern void *drm_realloc(void *oldpt, si
4998 extern DRM_AGP_MEM *drm_alloc_agp(struct drm_device *dev, int pages, u32 type);
4999 extern int drm_free_agp(DRM_AGP_MEM * handle, int pages);
5000 extern int drm_bind_agp(DRM_AGP_MEM * handle, unsigned int start);
5001+extern DRM_AGP_MEM *drm_agp_bind_pages(struct drm_device *dev,
5002+ struct page **pages,
5003+ unsigned long num_pages,
5004+ uint32_t gtt_offset);
5005 extern int drm_unbind_agp(DRM_AGP_MEM * handle);
5006
5007 /* Misc. IOCTL support (drm_ioctl.h) */
5008@@ -929,6 +1016,9 @@ extern int drm_getmagic(struct drm_devic
5009 extern int drm_authmagic(struct drm_device *dev, void *data,
5010 struct drm_file *file_priv);
5011
5012+/* Cache management (drm_cache.c) */
5013+void drm_clflush_pages(struct page *pages[], unsigned long num_pages);
5014+
5015 /* Locking IOCTL support (drm_lock.h) */
5016 extern int drm_lock(struct drm_device *dev, void *data,
5017 struct drm_file *file_priv);
5018@@ -1026,6 +1116,7 @@ extern DRM_AGP_MEM *drm_agp_allocate_mem
5019 extern int drm_agp_free_memory(DRM_AGP_MEM * handle);
5020 extern int drm_agp_bind_memory(DRM_AGP_MEM * handle, off_t start);
5021 extern int drm_agp_unbind_memory(DRM_AGP_MEM * handle);
5022+extern void drm_agp_chipset_flush(struct drm_device *dev);
5023
5024 /* Stub support (drm_stub.h) */
5025 extern int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
5026@@ -1088,6 +1179,66 @@ extern unsigned long drm_mm_tail_space(s
5027 extern int drm_mm_remove_space_from_tail(struct drm_mm *mm, unsigned long size);
5028 extern int drm_mm_add_space_to_tail(struct drm_mm *mm, unsigned long size);
5029
5030+/* Graphics Execution Manager library functions (drm_gem.c) */
5031+int drm_gem_init(struct drm_device *dev);
5032+void drm_gem_object_free(struct kref *kref);
5033+struct drm_gem_object *drm_gem_object_alloc(struct drm_device *dev,
5034+ size_t size);
5035+void drm_gem_object_handle_free(struct kref *kref);
5036+
5037+static inline void
5038+drm_gem_object_reference(struct drm_gem_object *obj)
5039+{
5040+ kref_get(&obj->refcount);
5041+}
5042+
5043+static inline void
5044+drm_gem_object_unreference(struct drm_gem_object *obj)
5045+{
5046+ if (obj == NULL)
5047+ return;
5048+
5049+ kref_put(&obj->refcount, drm_gem_object_free);
5050+}
5051+
5052+int drm_gem_handle_create(struct drm_file *file_priv,
5053+ struct drm_gem_object *obj,
5054+ int *handlep);
5055+
5056+static inline void
5057+drm_gem_object_handle_reference(struct drm_gem_object *obj)
5058+{
5059+ drm_gem_object_reference(obj);
5060+ kref_get(&obj->handlecount);
5061+}
5062+
5063+static inline void
5064+drm_gem_object_handle_unreference(struct drm_gem_object *obj)
5065+{
5066+ if (obj == NULL)
5067+ return;
5068+
5069+ /*
5070+ * Must bump handle count first as this may be the last
5071+ * ref, in which case the object would disappear before we
5072+ * checked for a name
5073+ */
5074+ kref_put(&obj->handlecount, drm_gem_object_handle_free);
5075+ drm_gem_object_unreference(obj);
5076+}
5077+
5078+struct drm_gem_object *drm_gem_object_lookup(struct drm_device *dev,
5079+ struct drm_file *filp,
5080+ int handle);
5081+int drm_gem_close_ioctl(struct drm_device *dev, void *data,
5082+ struct drm_file *file_priv);
5083+int drm_gem_flink_ioctl(struct drm_device *dev, void *data,
5084+ struct drm_file *file_priv);
5085+int drm_gem_open_ioctl(struct drm_device *dev, void *data,
5086+ struct drm_file *file_priv);
5087+void drm_gem_open(struct drm_device *dev, struct drm_file *file_private);
5088+void drm_gem_release(struct drm_device *dev, struct drm_file *file_private);
5089+
5090 extern void drm_core_ioremap(struct drm_map *map, struct drm_device *dev);
5091 extern void drm_core_ioremap_wc(struct drm_map *map, struct drm_device *dev);
5092 extern void drm_core_ioremapfree(struct drm_map *map, struct drm_device *dev);
5093--- a/include/drm/i915_drm.h
5094+++ b/include/drm/i915_drm.h
5095@@ -143,6 +143,22 @@ typedef struct _drm_i915_sarea {
5096 #define DRM_I915_GET_VBLANK_PIPE 0x0e
5097 #define DRM_I915_VBLANK_SWAP 0x0f
5098 #define DRM_I915_HWS_ADDR 0x11
5099+#define DRM_I915_GEM_INIT 0x13
5100+#define DRM_I915_GEM_EXECBUFFER 0x14
5101+#define DRM_I915_GEM_PIN 0x15
5102+#define DRM_I915_GEM_UNPIN 0x16
5103+#define DRM_I915_GEM_BUSY 0x17
5104+#define DRM_I915_GEM_THROTTLE 0x18
5105+#define DRM_I915_GEM_ENTERVT 0x19
5106+#define DRM_I915_GEM_LEAVEVT 0x1a
5107+#define DRM_I915_GEM_CREATE 0x1b
5108+#define DRM_I915_GEM_PREAD 0x1c
5109+#define DRM_I915_GEM_PWRITE 0x1d
5110+#define DRM_I915_GEM_MMAP 0x1e
5111+#define DRM_I915_GEM_SET_DOMAIN 0x1f
5112+#define DRM_I915_GEM_SW_FINISH 0x20
5113+#define DRM_I915_GEM_SET_TILING 0x21
5114+#define DRM_I915_GEM_GET_TILING 0x22
5115
5116 #define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t)
5117 #define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH)
5118@@ -160,6 +176,20 @@ typedef struct _drm_i915_sarea {
5119 #define DRM_IOCTL_I915_SET_VBLANK_PIPE DRM_IOW( DRM_COMMAND_BASE + DRM_I915_SET_VBLANK_PIPE, drm_i915_vblank_pipe_t)
5120 #define DRM_IOCTL_I915_GET_VBLANK_PIPE DRM_IOR( DRM_COMMAND_BASE + DRM_I915_GET_VBLANK_PIPE, drm_i915_vblank_pipe_t)
5121 #define DRM_IOCTL_I915_VBLANK_SWAP DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_VBLANK_SWAP, drm_i915_vblank_swap_t)
5122+#define DRM_IOCTL_I915_GEM_PIN DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_PIN, struct drm_i915_gem_pin)
5123+#define DRM_IOCTL_I915_GEM_UNPIN DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_UNPIN, struct drm_i915_gem_unpin)
5124+#define DRM_IOCTL_I915_GEM_BUSY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_BUSY, struct drm_i915_gem_busy)
5125+#define DRM_IOCTL_I915_GEM_THROTTLE DRM_IO ( DRM_COMMAND_BASE + DRM_I915_GEM_THROTTLE)
5126+#define DRM_IOCTL_I915_GEM_ENTERVT DRM_IO(DRM_COMMAND_BASE + DRM_I915_GEM_ENTERVT)
5127+#define DRM_IOCTL_I915_GEM_LEAVEVT DRM_IO(DRM_COMMAND_BASE + DRM_I915_GEM_LEAVEVT)
5128+#define DRM_IOCTL_I915_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_CREATE, struct drm_i915_gem_create)
5129+#define DRM_IOCTL_I915_GEM_PREAD DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_PREAD, struct drm_i915_gem_pread)
5130+#define DRM_IOCTL_I915_GEM_PWRITE DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_PWRITE, struct drm_i915_gem_pwrite)
5131+#define DRM_IOCTL_I915_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MMAP, struct drm_i915_gem_mmap)
5132+#define DRM_IOCTL_I915_GEM_SET_DOMAIN DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_SET_DOMAIN, struct drm_i915_gem_set_domain)
5133+#define DRM_IOCTL_I915_GEM_SW_FINISH DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_SW_FINISH, struct drm_i915_gem_sw_finish)
5134+#define DRM_IOCTL_I915_GEM_SET_TILING DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_SET_TILING, struct drm_i915_gem_set_tiling)
5135+#define DRM_IOCTL_I915_GEM_GET_TILING DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_GET_TILING, struct drm_i915_gem_get_tiling)
5136
5137 /* Allow drivers to submit batchbuffers directly to hardware, relying
5138 * on the security mechanisms provided by hardware.
5139@@ -200,6 +230,7 @@ typedef struct drm_i915_irq_wait {
5140 #define I915_PARAM_IRQ_ACTIVE 1
5141 #define I915_PARAM_ALLOW_BATCHBUFFER 2
5142 #define I915_PARAM_LAST_DISPATCH 3
5143+#define I915_PARAM_HAS_GEM 5
5144
5145 typedef struct drm_i915_getparam {
5146 int param;
5147@@ -267,4 +298,305 @@ typedef struct drm_i915_hws_addr {
5148 uint64_t addr;
5149 } drm_i915_hws_addr_t;
5150
5151+struct drm_i915_gem_init {
5152+ /**
5153+ * Beginning offset in the GTT to be managed by the DRM memory
5154+ * manager.
5155+ */
5156+ uint64_t gtt_start;
5157+ /**
5158+ * Ending offset in the GTT to be managed by the DRM memory
5159+ * manager.
5160+ */
5161+ uint64_t gtt_end;
5162+};
5163+
5164+struct drm_i915_gem_create {
5165+ /**
5166+ * Requested size for the object.
5167+ *
5168+ * The (page-aligned) allocated size for the object will be returned.
5169+ */
5170+ uint64_t size;
5171+ /**
5172+ * Returned handle for the object.
5173+ *
5174+ * Object handles are nonzero.
5175+ */
5176+ uint32_t handle;
5177+ uint32_t pad;
5178+};
5179+
5180+struct drm_i915_gem_pread {
5181+ /** Handle for the object being read. */
5182+ uint32_t handle;
5183+ uint32_t pad;
5184+ /** Offset into the object to read from */
5185+ uint64_t offset;
5186+ /** Length of data to read */
5187+ uint64_t size;
5188+ /**
5189+ * Pointer to write the data into.
5190+ *
5191+ * This is a fixed-size type for 32/64 compatibility.
5192+ */
5193+ uint64_t data_ptr;
5194+};
5195+
5196+struct drm_i915_gem_pwrite {
5197+ /** Handle for the object being written to. */
5198+ uint32_t handle;
5199+ uint32_t pad;
5200+ /** Offset into the object to write to */
5201+ uint64_t offset;
5202+ /** Length of data to write */
5203+ uint64_t size;
5204+ /**
5205+ * Pointer to read the data from.
5206+ *
5207+ * This is a fixed-size type for 32/64 compatibility.
5208+ */
5209+ uint64_t data_ptr;
5210+};
5211+
5212+struct drm_i915_gem_mmap {
5213+ /** Handle for the object being mapped. */
5214+ uint32_t handle;
5215+ uint32_t pad;
5216+ /** Offset in the object to map. */
5217+ uint64_t offset;
5218+ /**
5219+ * Length of data to map.
5220+ *
5221+ * The value will be page-aligned.
5222+ */
5223+ uint64_t size;
5224+ /**
5225+ * Returned pointer the data was mapped at.
5226+ *
5227+ * This is a fixed-size type for 32/64 compatibility.
5228+ */
5229+ uint64_t addr_ptr;
5230+};
5231+
5232+struct drm_i915_gem_set_domain {
5233+ /** Handle for the object */
5234+ uint32_t handle;
5235+
5236+ /** New read domains */
5237+ uint32_t read_domains;
5238+
5239+ /** New write domain */
5240+ uint32_t write_domain;
5241+};
5242+
5243+struct drm_i915_gem_sw_finish {
5244+ /** Handle for the object */
5245+ uint32_t handle;
5246+};
5247+
5248+struct drm_i915_gem_relocation_entry {
5249+ /**
5250+ * Handle of the buffer being pointed to by this relocation entry.
5251+ *
5252+ * It's appealing to make this be an index into the mm_validate_entry
5253+ * list to refer to the buffer, but this allows the driver to create
5254+ * a relocation list for state buffers and not re-write it per
5255+ * exec using the buffer.
5256+ */
5257+ uint32_t target_handle;
5258+
5259+ /**
5260+ * Value to be added to the offset of the target buffer to make up
5261+ * the relocation entry.
5262+ */
5263+ uint32_t delta;
5264+
5265+ /** Offset in the buffer the relocation entry will be written into */
5266+ uint64_t offset;
5267+
5268+ /**
5269+ * Offset value of the target buffer that the relocation entry was last
5270+ * written as.
5271+ *
5272+ * If the buffer has the same offset as last time, we can skip syncing
5273+ * and writing the relocation. This value is written back out by
5274+ * the execbuffer ioctl when the relocation is written.
5275+ */
5276+ uint64_t presumed_offset;
5277+
5278+ /**
5279+ * Target memory domains read by this operation.
5280+ */
5281+ uint32_t read_domains;
5282+
5283+ /**
5284+ * Target memory domains written by this operation.
5285+ *
5286+ * Note that only one domain may be written by the whole
5287+ * execbuffer operation, so that where there are conflicts,
5288+ * the application will get -EINVAL back.
5289+ */
5290+ uint32_t write_domain;
5291+};
5292+
5293+/** @{
5294+ * Intel memory domains
5295+ *
5296+ * Most of these just align with the various caches in
5297+ * the system and are used to flush and invalidate as
5298+ * objects end up cached in different domains.
5299+ */
5300+/** CPU cache */
5301+#define I915_GEM_DOMAIN_CPU 0x00000001
5302+/** Render cache, used by 2D and 3D drawing */
5303+#define I915_GEM_DOMAIN_RENDER 0x00000002
5304+/** Sampler cache, used by texture engine */
5305+#define I915_GEM_DOMAIN_SAMPLER 0x00000004
5306+/** Command queue, used to load batch buffers */
5307+#define I915_GEM_DOMAIN_COMMAND 0x00000008
5308+/** Instruction cache, used by shader programs */
5309+#define I915_GEM_DOMAIN_INSTRUCTION 0x00000010
5310+/** Vertex address cache */
5311+#define I915_GEM_DOMAIN_VERTEX 0x00000020
5312+/** GTT domain - aperture and scanout */
5313+#define I915_GEM_DOMAIN_GTT 0x00000040
5314+/** @} */
5315+
5316+struct drm_i915_gem_exec_object {
5317+ /**
5318+ * User's handle for a buffer to be bound into the GTT for this
5319+ * operation.
5320+ */
5321+ uint32_t handle;
5322+
5323+ /** Number of relocations to be performed on this buffer */
5324+ uint32_t relocation_count;
5325+ /**
5326+ * Pointer to array of struct drm_i915_gem_relocation_entry containing
5327+ * the relocations to be performed in this buffer.
5328+ */
5329+ uint64_t relocs_ptr;
5330+
5331+ /** Required alignment in graphics aperture */
5332+ uint64_t alignment;
5333+
5334+ /**
5335+ * Returned value of the updated offset of the object, for future
5336+ * presumed_offset writes.
5337+ */
5338+ uint64_t offset;
5339+};
5340+
5341+struct drm_i915_gem_execbuffer {
5342+ /**
5343+ * List of buffers to be validated with their relocations to be
5344+ * performend on them.
5345+ *
5346+ * This is a pointer to an array of struct drm_i915_gem_validate_entry.
5347+ *
5348+ * These buffers must be listed in an order such that all relocations
5349+ * a buffer is performing refer to buffers that have already appeared
5350+ * in the validate list.
5351+ */
5352+ uint64_t buffers_ptr;
5353+ uint32_t buffer_count;
5354+
5355+ /** Offset in the batchbuffer to start execution from. */
5356+ uint32_t batch_start_offset;
5357+ /** Bytes used in batchbuffer from batch_start_offset */
5358+ uint32_t batch_len;
5359+ uint32_t DR1;
5360+ uint32_t DR4;
5361+ uint32_t num_cliprects;
5362+ /** This is a struct drm_clip_rect *cliprects */
5363+ uint64_t cliprects_ptr;
5364+};
5365+
5366+struct drm_i915_gem_pin {
5367+ /** Handle of the buffer to be pinned. */
5368+ uint32_t handle;
5369+ uint32_t pad;
5370+
5371+ /** alignment required within the aperture */
5372+ uint64_t alignment;
5373+
5374+ /** Returned GTT offset of the buffer. */
5375+ uint64_t offset;
5376+};
5377+
5378+struct drm_i915_gem_unpin {
5379+ /** Handle of the buffer to be unpinned. */
5380+ uint32_t handle;
5381+ uint32_t pad;
5382+};
5383+
5384+struct drm_i915_gem_busy {
5385+ /** Handle of the buffer to check for busy */
5386+ uint32_t handle;
5387+
5388+ /** Return busy status (1 if busy, 0 if idle) */
5389+ uint32_t busy;
5390+};
5391+
5392+#define I915_TILING_NONE 0
5393+#define I915_TILING_X 1
5394+#define I915_TILING_Y 2
5395+
5396+#define I915_BIT_6_SWIZZLE_NONE 0
5397+#define I915_BIT_6_SWIZZLE_9 1
5398+#define I915_BIT_6_SWIZZLE_9_10 2
5399+#define I915_BIT_6_SWIZZLE_9_11 3
5400+#define I915_BIT_6_SWIZZLE_9_10_11 4
5401+/* Not seen by userland */
5402+#define I915_BIT_6_SWIZZLE_UNKNOWN 5
5403+
5404+struct drm_i915_gem_set_tiling {
5405+ /** Handle of the buffer to have its tiling state updated */
5406+ uint32_t handle;
5407+
5408+ /**
5409+ * Tiling mode for the object (I915_TILING_NONE, I915_TILING_X,
5410+ * I915_TILING_Y).
5411+ *
5412+ * This value is to be set on request, and will be updated by the
5413+ * kernel on successful return with the actual chosen tiling layout.
5414+ *
5415+ * The tiling mode may be demoted to I915_TILING_NONE when the system
5416+ * has bit 6 swizzling that can't be managed correctly by GEM.
5417+ *
5418+ * Buffer contents become undefined when changing tiling_mode.
5419+ */
5420+ uint32_t tiling_mode;
5421+
5422+ /**
5423+ * Stride in bytes for the object when in I915_TILING_X or
5424+ * I915_TILING_Y.
5425+ */
5426+ uint32_t stride;
5427+
5428+ /**
5429+ * Returned address bit 6 swizzling required for CPU access through
5430+ * mmap mapping.
5431+ */
5432+ uint32_t swizzle_mode;
5433+};
5434+
5435+struct drm_i915_gem_get_tiling {
5436+ /** Handle of the buffer to get tiling state for. */
5437+ uint32_t handle;
5438+
5439+ /**
5440+ * Current tiling mode for the object (I915_TILING_NONE, I915_TILING_X,
5441+ * I915_TILING_Y).
5442+ */
5443+ uint32_t tiling_mode;
5444+
5445+ /**
5446+ * Returned address bit 6 swizzling required for CPU access through
5447+ * mmap mapping.
5448+ */
5449+ uint32_t swizzle_mode;
5450+};
5451+
5452 #endif /* _I915_DRM_H_ */
5453
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27-rc1/0009-squashfs3.3-2.6.27.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc1/0009-squashfs3.3-2.6.27.patch
new file mode 100644
index 0000000000..4de9839c76
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc1/0009-squashfs3.3-2.6.27.patch
@@ -0,0 +1,6727 @@
1diff -uNr a/fs/Kconfig b/fs/Kconfig
2--- a/fs/Kconfig 2008-07-28 19:40:31.000000000 -0700
3+++ b/fs/Kconfig 2008-08-13 16:19:56.000000000 -0700
4@@ -1348,6 +1348,56 @@
5
6 If unsure, say N.
7
8+config SQUASHFS
9+ tristate "SquashFS 3.3 - Squashed file system support"
10+ select ZLIB_INFLATE
11+ help
12+ Saying Y here includes support for SquashFS 3.3 (a Compressed
13+ Read-Only File System). Squashfs is a highly compressed read-only
14+ filesystem for Linux. It uses zlib compression to compress both
15+ files, inodes and directories. Inodes in the system are very small
16+ and all blocks are packed to minimise data overhead. Block sizes
17+ greater than 4K are supported up to a maximum of 1 Mbytes (default
18+ block size 128K). SquashFS 3.3 supports 64 bit filesystems and files
19+ (larger than 4GB), full uid/gid information, hard links and timestamps.
20+
21+ Squashfs is intended for general read-only filesystem use, for
22+ archival use (i.e. in cases where a .tar.gz file may be used), and in
23+ embedded systems where low overhead is needed. Further information
24+ and filesystem tools are available from http://squashfs.sourceforge.net.
25+
26+ If you want to compile this as a module ( = code which can be
27+ inserted in and removed from the running kernel whenever you want),
28+ say M here and read <file:Documentation/modules.txt>. The module
29+ will be called squashfs. Note that the root file system (the one
30+ containing the directory /) cannot be compiled as a module.
31+
32+ If unsure, say N.
33+
34+config SQUASHFS_EMBEDDED
35+
36+ bool "Additional option for memory-constrained systems"
37+ depends on SQUASHFS
38+ default n
39+ help
40+ Saying Y here allows you to specify cache size.
41+
42+ If unsure, say N.
43+
44+config SQUASHFS_FRAGMENT_CACHE_SIZE
45+ int "Number of fragments cached" if SQUASHFS_EMBEDDED
46+ depends on SQUASHFS
47+ default "3"
48+ help
49+ By default SquashFS caches the last 3 fragments read from
50+ the filesystem. Increasing this amount may mean SquashFS
51+ has to re-read fragments less often from disk, at the expense
52+ of extra system memory. Decreasing this amount will mean
53+ SquashFS uses less memory at the expense of extra reads from disk.
54+
55+ Note there must be at least one cached fragment. Anything
56+ much more than three will probably not make much difference.
57+
58 config VXFS_FS
59 tristate "FreeVxFS file system support (VERITAS VxFS(TM) compatible)"
60 depends on BLOCK
61diff -uNr a/fs/Kconfig.orig b/fs/Kconfig.orig
62--- a/fs/Kconfig.orig 1969-12-31 16:00:00.000000000 -0800
63+++ b/fs/Kconfig.orig 2008-07-28 19:40:31.000000000 -0700
64@@ -0,0 +1,2097 @@
65+#
66+# File system configuration
67+#
68+
69+menu "File systems"
70+
71+if BLOCK
72+
73+config EXT2_FS
74+ tristate "Second extended fs support"
75+ help
76+ Ext2 is a standard Linux file system for hard disks.
77+
78+ To compile this file system support as a module, choose M here: the
79+ module will be called ext2.
80+
81+ If unsure, say Y.
82+
83+config EXT2_FS_XATTR
84+ bool "Ext2 extended attributes"
85+ depends on EXT2_FS
86+ help
87+ Extended attributes are name:value pairs associated with inodes by
88+ the kernel or by users (see the attr(5) manual page, or visit
89+ <http://acl.bestbits.at/> for details).
90+
91+ If unsure, say N.
92+
93+config EXT2_FS_POSIX_ACL
94+ bool "Ext2 POSIX Access Control Lists"
95+ depends on EXT2_FS_XATTR
96+ select FS_POSIX_ACL
97+ help
98+ Posix Access Control Lists (ACLs) support permissions for users and
99+ groups beyond the owner/group/world scheme.
100+
101+ To learn more about Access Control Lists, visit the Posix ACLs for
102+ Linux website <http://acl.bestbits.at/>.
103+
104+ If you don't know what Access Control Lists are, say N
105+
106+config EXT2_FS_SECURITY
107+ bool "Ext2 Security Labels"
108+ depends on EXT2_FS_XATTR
109+ help
110+ Security labels support alternative access control models
111+ implemented by security modules like SELinux. This option
112+ enables an extended attribute handler for file security
113+ labels in the ext2 filesystem.
114+
115+ If you are not using a security module that requires using
116+ extended attributes for file security labels, say N.
117+
118+config EXT2_FS_XIP
119+ bool "Ext2 execute in place support"
120+ depends on EXT2_FS && MMU
121+ help
122+ Execute in place can be used on memory-backed block devices. If you
123+ enable this option, you can select to mount block devices which are
124+ capable of this feature without using the page cache.
125+
126+ If you do not use a block device that is capable of using this,
127+ or if unsure, say N.
128+
129+config FS_XIP
130+# execute in place
131+ bool
132+ depends on EXT2_FS_XIP
133+ default y
134+
135+config EXT3_FS
136+ tristate "Ext3 journalling file system support"
137+ select JBD
138+ help
139+ This is the journalling version of the Second extended file system
140+ (often called ext3), the de facto standard Linux file system
141+ (method to organize files on a storage device) for hard disks.
142+
143+ The journalling code included in this driver means you do not have
144+ to run e2fsck (file system checker) on your file systems after a
145+ crash. The journal keeps track of any changes that were being made
146+ at the time the system crashed, and can ensure that your file system
147+ is consistent without the need for a lengthy check.
148+
149+ Other than adding the journal to the file system, the on-disk format
150+ of ext3 is identical to ext2. It is possible to freely switch
151+ between using the ext3 driver and the ext2 driver, as long as the
152+ file system has been cleanly unmounted, or e2fsck is run on the file
153+ system.
154+
155+ To add a journal on an existing ext2 file system or change the
156+ behavior of ext3 file systems, you can use the tune2fs utility ("man
157+ tune2fs"). To modify attributes of files and directories on ext3
158+ file systems, use chattr ("man chattr"). You need to be using
159+ e2fsprogs version 1.20 or later in order to create ext3 journals
160+ (available at <http://sourceforge.net/projects/e2fsprogs/>).
161+
162+ To compile this file system support as a module, choose M here: the
163+ module will be called ext3.
164+
165+config EXT3_FS_XATTR
166+ bool "Ext3 extended attributes"
167+ depends on EXT3_FS
168+ default y
169+ help
170+ Extended attributes are name:value pairs associated with inodes by
171+ the kernel or by users (see the attr(5) manual page, or visit
172+ <http://acl.bestbits.at/> for details).
173+
174+ If unsure, say N.
175+
176+ You need this for POSIX ACL support on ext3.
177+
178+config EXT3_FS_POSIX_ACL
179+ bool "Ext3 POSIX Access Control Lists"
180+ depends on EXT3_FS_XATTR
181+ select FS_POSIX_ACL
182+ help
183+ Posix Access Control Lists (ACLs) support permissions for users and
184+ groups beyond the owner/group/world scheme.
185+
186+ To learn more about Access Control Lists, visit the Posix ACLs for
187+ Linux website <http://acl.bestbits.at/>.
188+
189+ If you don't know what Access Control Lists are, say N
190+
191+config EXT3_FS_SECURITY
192+ bool "Ext3 Security Labels"
193+ depends on EXT3_FS_XATTR
194+ help
195+ Security labels support alternative access control models
196+ implemented by security modules like SELinux. This option
197+ enables an extended attribute handler for file security
198+ labels in the ext3 filesystem.
199+
200+ If you are not using a security module that requires using
201+ extended attributes for file security labels, say N.
202+
203+config EXT4DEV_FS
204+ tristate "Ext4dev/ext4 extended fs support development (EXPERIMENTAL)"
205+ depends on EXPERIMENTAL
206+ select JBD2
207+ select CRC16
208+ help
209+ Ext4dev is a predecessor filesystem of the next generation
210+ extended fs ext4, based on ext3 filesystem code. It will be
211+ renamed ext4 fs later, once ext4dev is mature and stabilized.
212+
213+ Unlike the change from ext2 filesystem to ext3 filesystem,
214+ the on-disk format of ext4dev is not the same as ext3 any more:
215+ it is based on extent maps and it supports 48-bit physical block
216+ numbers. These combined on-disk format changes will allow
217+ ext4dev/ext4 to handle more than 16 TB filesystem volumes --
218+ a hard limit that ext3 cannot overcome without changing the
219+ on-disk format.
220+
221+ Other than extent maps and 48-bit block numbers, ext4dev also is
222+ likely to have other new features such as persistent preallocation,
223+ high resolution time stamps, and larger file support etc. These
224+ features will be added to ext4dev gradually.
225+
226+ To compile this file system support as a module, choose M here. The
227+ module will be called ext4dev.
228+
229+ If unsure, say N.
230+
231+config EXT4DEV_FS_XATTR
232+ bool "Ext4dev extended attributes"
233+ depends on EXT4DEV_FS
234+ default y
235+ help
236+ Extended attributes are name:value pairs associated with inodes by
237+ the kernel or by users (see the attr(5) manual page, or visit
238+ <http://acl.bestbits.at/> for details).
239+
240+ If unsure, say N.
241+
242+ You need this for POSIX ACL support on ext4dev/ext4.
243+
244+config EXT4DEV_FS_POSIX_ACL
245+ bool "Ext4dev POSIX Access Control Lists"
246+ depends on EXT4DEV_FS_XATTR
247+ select FS_POSIX_ACL
248+ help
249+ POSIX Access Control Lists (ACLs) support permissions for users and
250+ groups beyond the owner/group/world scheme.
251+
252+ To learn more about Access Control Lists, visit the POSIX ACLs for
253+ Linux website <http://acl.bestbits.at/>.
254+
255+ If you don't know what Access Control Lists are, say N
256+
257+config EXT4DEV_FS_SECURITY
258+ bool "Ext4dev Security Labels"
259+ depends on EXT4DEV_FS_XATTR
260+ help
261+ Security labels support alternative access control models
262+ implemented by security modules like SELinux. This option
263+ enables an extended attribute handler for file security
264+ labels in the ext4dev/ext4 filesystem.
265+
266+ If you are not using a security module that requires using
267+ extended attributes for file security labels, say N.
268+
269+config JBD
270+ tristate
271+ help
272+ This is a generic journalling layer for block devices. It is
273+ currently used by the ext3 and OCFS2 file systems, but it could
274+ also be used to add journal support to other file systems or block
275+ devices such as RAID or LVM.
276+
277+ If you are using the ext3 or OCFS2 file systems, you need to
278+ say Y here. If you are not using ext3 OCFS2 then you will probably
279+ want to say N.
280+
281+ To compile this device as a module, choose M here: the module will be
282+ called jbd. If you are compiling ext3 or OCFS2 into the kernel,
283+ you cannot compile this code as a module.
284+
285+config JBD_DEBUG
286+ bool "JBD (ext3) debugging support"
287+ depends on JBD && DEBUG_FS
288+ help
289+ If you are using the ext3 journaled file system (or potentially any
290+ other file system/device using JBD), this option allows you to
291+ enable debugging output while the system is running, in order to
292+ help track down any problems you are having. By default the
293+ debugging output will be turned off.
294+
295+ If you select Y here, then you will be able to turn on debugging
296+ with "echo N > /sys/kernel/debug/jbd/jbd-debug", where N is a
297+ number between 1 and 5, the higher the number, the more debugging
298+ output is generated. To turn debugging off again, do
299+ "echo 0 > /sys/kernel/debug/jbd/jbd-debug".
300+
301+config JBD2
302+ tristate
303+ select CRC32
304+ help
305+ This is a generic journaling layer for block devices that support
306+ both 32-bit and 64-bit block numbers. It is currently used by
307+ the ext4dev/ext4 filesystem, but it could also be used to add
308+ journal support to other file systems or block devices such
309+ as RAID or LVM.
310+
311+ If you are using ext4dev/ext4, you need to say Y here. If you are not
312+ using ext4dev/ext4 then you will probably want to say N.
313+
314+ To compile this device as a module, choose M here. The module will be
315+ called jbd2. If you are compiling ext4dev/ext4 into the kernel,
316+ you cannot compile this code as a module.
317+
318+config JBD2_DEBUG
319+ bool "JBD2 (ext4dev/ext4) debugging support"
320+ depends on JBD2 && DEBUG_FS
321+ help
322+ If you are using the ext4dev/ext4 journaled file system (or
323+ potentially any other filesystem/device using JBD2), this option
324+ allows you to enable debugging output while the system is running,
325+ in order to help track down any problems you are having.
326+ By default, the debugging output will be turned off.
327+
328+ If you select Y here, then you will be able to turn on debugging
329+ with "echo N > /sys/kernel/debug/jbd2/jbd2-debug", where N is a
330+ number between 1 and 5. The higher the number, the more debugging
331+ output is generated. To turn debugging off again, do
332+ "echo 0 > /sys/kernel/debug/jbd2/jbd2-debug".
333+
334+config FS_MBCACHE
335+# Meta block cache for Extended Attributes (ext2/ext3/ext4)
336+ tristate
337+ depends on EXT2_FS_XATTR || EXT3_FS_XATTR || EXT4DEV_FS_XATTR
338+ default y if EXT2_FS=y || EXT3_FS=y || EXT4DEV_FS=y
339+ default m if EXT2_FS=m || EXT3_FS=m || EXT4DEV_FS=m
340+
341+config REISERFS_FS
342+ tristate "Reiserfs support"
343+ help
344+ Stores not just filenames but the files themselves in a balanced
345+ tree. Uses journalling.
346+
347+ Balanced trees are more efficient than traditional file system
348+ architectural foundations.
349+
350+ In general, ReiserFS is as fast as ext2, but is very efficient with
351+ large directories and small files. Additional patches are needed
352+ for NFS and quotas, please see <http://www.namesys.com/> for links.
353+
354+ It is more easily extended to have features currently found in
355+ database and keyword search systems than block allocation based file
356+ systems are. The next version will be so extended, and will support
357+ plugins consistent with our motto ``It takes more than a license to
358+ make source code open.''
359+
360+ Read <http://www.namesys.com/> to learn more about reiserfs.
361+
362+ Sponsored by Threshold Networks, Emusic.com, and Bigstorage.com.
363+
364+ If you like it, you can pay us to add new features to it that you
365+ need, buy a support contract, or pay us to port it to another OS.
366+
367+config REISERFS_CHECK
368+ bool "Enable reiserfs debug mode"
369+ depends on REISERFS_FS
370+ help
371+ If you set this to Y, then ReiserFS will perform every check it can
372+ possibly imagine of its internal consistency throughout its
373+ operation. It will also go substantially slower. More than once we
374+ have forgotten that this was on, and then gone despondent over the
375+ latest benchmarks.:-) Use of this option allows our team to go all
376+ out in checking for consistency when debugging without fear of its
377+ effect on end users. If you are on the verge of sending in a bug
378+ report, say Y and you might get a useful error message. Almost
379+ everyone should say N.
380+
381+config REISERFS_PROC_INFO
382+ bool "Stats in /proc/fs/reiserfs"
383+ depends on REISERFS_FS && PROC_FS
384+ help
385+ Create under /proc/fs/reiserfs a hierarchy of files, displaying
386+ various ReiserFS statistics and internal data at the expense of
387+ making your kernel or module slightly larger (+8 KB). This also
388+ increases the amount of kernel memory required for each mount.
389+ Almost everyone but ReiserFS developers and people fine-tuning
390+ reiserfs or tracing problems should say N.
391+
392+config REISERFS_FS_XATTR
393+ bool "ReiserFS extended attributes"
394+ depends on REISERFS_FS
395+ help
396+ Extended attributes are name:value pairs associated with inodes by
397+ the kernel or by users (see the attr(5) manual page, or visit
398+ <http://acl.bestbits.at/> for details).
399+
400+ If unsure, say N.
401+
402+config REISERFS_FS_POSIX_ACL
403+ bool "ReiserFS POSIX Access Control Lists"
404+ depends on REISERFS_FS_XATTR
405+ select FS_POSIX_ACL
406+ help
407+ Posix Access Control Lists (ACLs) support permissions for users and
408+ groups beyond the owner/group/world scheme.
409+
410+ To learn more about Access Control Lists, visit the Posix ACLs for
411+ Linux website <http://acl.bestbits.at/>.
412+
413+ If you don't know what Access Control Lists are, say N
414+
415+config REISERFS_FS_SECURITY
416+ bool "ReiserFS Security Labels"
417+ depends on REISERFS_FS_XATTR
418+ help
419+ Security labels support alternative access control models
420+ implemented by security modules like SELinux. This option
421+ enables an extended attribute handler for file security
422+ labels in the ReiserFS filesystem.
423+
424+ If you are not using a security module that requires using
425+ extended attributes for file security labels, say N.
426+
427+config JFS_FS
428+ tristate "JFS filesystem support"
429+ select NLS
430+ help
431+ This is a port of IBM's Journaled Filesystem . More information is
432+ available in the file <file:Documentation/filesystems/jfs.txt>.
433+
434+ If you do not intend to use the JFS filesystem, say N.
435+
436+config JFS_POSIX_ACL
437+ bool "JFS POSIX Access Control Lists"
438+ depends on JFS_FS
439+ select FS_POSIX_ACL
440+ help
441+ Posix Access Control Lists (ACLs) support permissions for users and
442+ groups beyond the owner/group/world scheme.
443+
444+ To learn more about Access Control Lists, visit the Posix ACLs for
445+ Linux website <http://acl.bestbits.at/>.
446+
447+ If you don't know what Access Control Lists are, say N
448+
449+config JFS_SECURITY
450+ bool "JFS Security Labels"
451+ depends on JFS_FS
452+ help
453+ Security labels support alternative access control models
454+ implemented by security modules like SELinux. This option
455+ enables an extended attribute handler for file security
456+ labels in the jfs filesystem.
457+
458+ If you are not using a security module that requires using
459+ extended attributes for file security labels, say N.
460+
461+config JFS_DEBUG
462+ bool "JFS debugging"
463+ depends on JFS_FS
464+ help
465+ If you are experiencing any problems with the JFS filesystem, say
466+ Y here. This will result in additional debugging messages to be
467+ written to the system log. Under normal circumstances, this
468+ results in very little overhead.
469+
470+config JFS_STATISTICS
471+ bool "JFS statistics"
472+ depends on JFS_FS
473+ help
474+ Enabling this option will cause statistics from the JFS file system
475+ to be made available to the user in the /proc/fs/jfs/ directory.
476+
477+config FS_POSIX_ACL
478+# Posix ACL utility routines (for now, only ext2/ext3/jfs/reiserfs/nfs4)
479+#
480+# NOTE: you can implement Posix ACLs without these helpers (XFS does).
481+# Never use this symbol for ifdefs.
482+#
483+ bool
484+ default n
485+
486+source "fs/xfs/Kconfig"
487+source "fs/gfs2/Kconfig"
488+
489+config OCFS2_FS
490+ tristate "OCFS2 file system support"
491+ depends on NET && SYSFS
492+ select CONFIGFS_FS
493+ select JBD
494+ select CRC32
495+ help
496+ OCFS2 is a general purpose extent based shared disk cluster file
497+ system with many similarities to ext3. It supports 64 bit inode
498+ numbers, and has automatically extending metadata groups which may
499+ also make it attractive for non-clustered use.
500+
501+ You'll want to install the ocfs2-tools package in order to at least
502+ get "mount.ocfs2".
503+
504+ Project web page: http://oss.oracle.com/projects/ocfs2
505+ Tools web page: http://oss.oracle.com/projects/ocfs2-tools
506+ OCFS2 mailing lists: http://oss.oracle.com/projects/ocfs2/mailman/
507+
508+ For more information on OCFS2, see the file
509+ <file:Documentation/filesystems/ocfs2.txt>.
510+
511+config OCFS2_FS_O2CB
512+ tristate "O2CB Kernelspace Clustering"
513+ depends on OCFS2_FS
514+ default y
515+ help
516+ OCFS2 includes a simple kernelspace clustering package, the OCFS2
517+ Cluster Base. It only requires a very small userspace component
518+ to configure it. This comes with the standard ocfs2-tools package.
519+ O2CB is limited to maintaining a cluster for OCFS2 file systems.
520+ It cannot manage any other cluster applications.
521+
522+ It is always safe to say Y here, as the clustering method is
523+ run-time selectable.
524+
525+config OCFS2_FS_USERSPACE_CLUSTER
526+ tristate "OCFS2 Userspace Clustering"
527+ depends on OCFS2_FS && DLM
528+ default y
529+ help
530+ This option will allow OCFS2 to use userspace clustering services
531+ in conjunction with the DLM in fs/dlm. If you are using a
532+ userspace cluster manager, say Y here.
533+
534+ It is safe to say Y, as the clustering method is run-time
535+ selectable.
536+
537+config OCFS2_FS_STATS
538+ bool "OCFS2 statistics"
539+ depends on OCFS2_FS
540+ default y
541+ help
542+ This option allows some fs statistics to be captured. Enabling
543+ this option may increase the memory consumption.
544+
545+config OCFS2_DEBUG_MASKLOG
546+ bool "OCFS2 logging support"
547+ depends on OCFS2_FS
548+ default y
549+ help
550+ The ocfs2 filesystem has an extensive logging system. The system
551+ allows selection of events to log via files in /sys/o2cb/logmask/.
552+ This option will enlarge your kernel, but it allows debugging of
553+ ocfs2 filesystem issues.
554+
555+config OCFS2_DEBUG_FS
556+ bool "OCFS2 expensive checks"
557+ depends on OCFS2_FS
558+ default n
559+ help
560+ This option will enable expensive consistency checks. Enable
561+ this option for debugging only as it is likely to decrease
562+ performance of the filesystem.
563+
564+endif # BLOCK
565+
566+config DNOTIFY
567+ bool "Dnotify support"
568+ default y
569+ help
570+ Dnotify is a directory-based per-fd file change notification system
571+ that uses signals to communicate events to user-space. There exist
572+ superior alternatives, but some applications may still rely on
573+ dnotify.
574+
575+ If unsure, say Y.
576+
577+config INOTIFY
578+ bool "Inotify file change notification support"
579+ default y
580+ ---help---
581+ Say Y here to enable inotify support. Inotify is a file change
582+ notification system and a replacement for dnotify. Inotify fixes
583+ numerous shortcomings in dnotify and introduces several new features
584+ including multiple file events, one-shot support, and unmount
585+ notification.
586+
587+ For more information, see <file:Documentation/filesystems/inotify.txt>
588+
589+ If unsure, say Y.
590+
591+config INOTIFY_USER
592+ bool "Inotify support for userspace"
593+ depends on INOTIFY
594+ default y
595+ ---help---
596+ Say Y here to enable inotify support for userspace, including the
597+ associated system calls. Inotify allows monitoring of both files and
598+ directories via a single open fd. Events are read from the file
599+ descriptor, which is also select()- and poll()-able.
600+
601+ For more information, see <file:Documentation/filesystems/inotify.txt>
602+
603+ If unsure, say Y.
604+
605+config QUOTA
606+ bool "Quota support"
607+ help
608+ If you say Y here, you will be able to set per user limits for disk
609+ usage (also called disk quotas). Currently, it works for the
610+ ext2, ext3, and reiserfs file system. ext3 also supports journalled
611+ quotas for which you don't need to run quotacheck(8) after an unclean
612+ shutdown.
613+ For further details, read the Quota mini-HOWTO, available from
614+ <http://www.tldp.org/docs.html#howto>, or the documentation provided
615+ with the quota tools. Probably the quota support is only useful for
616+ multi user systems. If unsure, say N.
617+
618+config QUOTA_NETLINK_INTERFACE
619+ bool "Report quota messages through netlink interface"
620+ depends on QUOTA && NET
621+ help
622+ If you say Y here, quota warnings (about exceeding softlimit, reaching
623+ hardlimit, etc.) will be reported through netlink interface. If unsure,
624+ say Y.
625+
626+config PRINT_QUOTA_WARNING
627+ bool "Print quota warnings to console (OBSOLETE)"
628+ depends on QUOTA
629+ default y
630+ help
631+ If you say Y here, quota warnings (about exceeding softlimit, reaching
632+ hardlimit, etc.) will be printed to the process' controlling terminal.
633+ Note that this behavior is currently deprecated and may go away in
634+ future. Please use notification via netlink socket instead.
635+
636+config QFMT_V1
637+ tristate "Old quota format support"
638+ depends on QUOTA
639+ help
640+ This quota format was (is) used by kernels earlier than 2.4.22. If
641+ you have quota working and you don't want to convert to new quota
642+ format say Y here.
643+
644+config QFMT_V2
645+ tristate "Quota format v2 support"
646+ depends on QUOTA
647+ help
648+ This quota format allows using quotas with 32-bit UIDs/GIDs. If you
649+ need this functionality say Y here.
650+
651+config QUOTACTL
652+ bool
653+ depends on XFS_QUOTA || QUOTA
654+ default y
655+
656+config AUTOFS_FS
657+ tristate "Kernel automounter support"
658+ help
659+ The automounter is a tool to automatically mount remote file systems
660+ on demand. This implementation is partially kernel-based to reduce
661+ overhead in the already-mounted case; this is unlike the BSD
662+ automounter (amd), which is a pure user space daemon.
663+
664+ To use the automounter you need the user-space tools from the autofs
665+ package; you can find the location in <file:Documentation/Changes>.
666+ You also want to answer Y to "NFS file system support", below.
667+
668+ If you want to use the newer version of the automounter with more
669+ features, say N here and say Y to "Kernel automounter v4 support",
670+ below.
671+
672+ To compile this support as a module, choose M here: the module will be
673+ called autofs.
674+
675+ If you are not a part of a fairly large, distributed network, you
676+ probably do not need an automounter, and can say N here.
677+
678+config AUTOFS4_FS
679+ tristate "Kernel automounter version 4 support (also supports v3)"
680+ help
681+ The automounter is a tool to automatically mount remote file systems
682+ on demand. This implementation is partially kernel-based to reduce
683+ overhead in the already-mounted case; this is unlike the BSD
684+ automounter (amd), which is a pure user space daemon.
685+
686+ To use the automounter you need the user-space tools from
687+ <ftp://ftp.kernel.org/pub/linux/daemons/autofs/v4/>; you also
688+ want to answer Y to "NFS file system support", below.
689+
690+ To compile this support as a module, choose M here: the module will be
691+ called autofs4. You will need to add "alias autofs autofs4" to your
692+ modules configuration file.
693+
694+ If you are not a part of a fairly large, distributed network or
695+ don't have a laptop which needs to dynamically reconfigure to the
696+ local network, you probably do not need an automounter, and can say
697+ N here.
698+
699+config FUSE_FS
700+ tristate "Filesystem in Userspace support"
701+ help
702+ With FUSE it is possible to implement a fully functional filesystem
703+ in a userspace program.
704+
705+ There's also companion library: libfuse. This library along with
706+ utilities is available from the FUSE homepage:
707+ <http://fuse.sourceforge.net/>
708+
709+ See <file:Documentation/filesystems/fuse.txt> for more information.
710+ See <file:Documentation/Changes> for needed library/utility version.
711+
712+ If you want to develop a userspace FS, or if you want to use
713+ a filesystem based on FUSE, answer Y or M.
714+
715+config GENERIC_ACL
716+ bool
717+ select FS_POSIX_ACL
718+
719+if BLOCK
720+menu "CD-ROM/DVD Filesystems"
721+
722+config ISO9660_FS
723+ tristate "ISO 9660 CDROM file system support"
724+ help
725+ This is the standard file system used on CD-ROMs. It was previously
726+ known as "High Sierra File System" and is called "hsfs" on other
727+ Unix systems. The so-called Rock-Ridge extensions which allow for
728+ long Unix filenames and symbolic links are also supported by this
729+ driver. If you have a CD-ROM drive and want to do more with it than
730+ just listen to audio CDs and watch its LEDs, say Y (and read
731+ <file:Documentation/filesystems/isofs.txt> and the CD-ROM-HOWTO,
732+ available from <http://www.tldp.org/docs.html#howto>), thereby
733+ enlarging your kernel by about 27 KB; otherwise say N.
734+
735+ To compile this file system support as a module, choose M here: the
736+ module will be called isofs.
737+
738+config JOLIET
739+ bool "Microsoft Joliet CDROM extensions"
740+ depends on ISO9660_FS
741+ select NLS
742+ help
743+ Joliet is a Microsoft extension for the ISO 9660 CD-ROM file system
744+ which allows for long filenames in unicode format (unicode is the
745+ new 16 bit character code, successor to ASCII, which encodes the
746+ characters of almost all languages of the world; see
747+ <http://www.unicode.org/> for more information). Say Y here if you
748+ want to be able to read Joliet CD-ROMs under Linux.
749+
750+config ZISOFS
751+ bool "Transparent decompression extension"
752+ depends on ISO9660_FS
753+ select ZLIB_INFLATE
754+ help
755+ This is a Linux-specific extension to RockRidge which lets you store
756+ data in compressed form on a CD-ROM and have it transparently
757+ decompressed when the CD-ROM is accessed. See
758+ <http://www.kernel.org/pub/linux/utils/fs/zisofs/> for the tools
759+ necessary to create such a filesystem. Say Y here if you want to be
760+ able to read such compressed CD-ROMs.
761+
762+config UDF_FS
763+ tristate "UDF file system support"
764+ select CRC_ITU_T
765+ help
766+ This is the new file system used on some CD-ROMs and DVDs. Say Y if
767+ you intend to mount DVD discs or CDRW's written in packet mode, or
768+ if written to by other UDF utilities, such as DirectCD.
769+ Please read <file:Documentation/filesystems/udf.txt>.
770+
771+ To compile this file system support as a module, choose M here: the
772+ module will be called udf.
773+
774+ If unsure, say N.
775+
776+config UDF_NLS
777+ bool
778+ default y
779+ depends on (UDF_FS=m && NLS) || (UDF_FS=y && NLS=y)
780+
781+endmenu
782+endif # BLOCK
783+
784+if BLOCK
785+menu "DOS/FAT/NT Filesystems"
786+
787+config FAT_FS
788+ tristate
789+ select NLS
790+ help
791+ If you want to use one of the FAT-based file systems (the MS-DOS and
792+ VFAT (Windows 95) file systems), then you must say Y or M here
793+ to include FAT support. You will then be able to mount partitions or
794+ diskettes with FAT-based file systems and transparently access the
795+ files on them, i.e. MSDOS files will look and behave just like all
796+ other Unix files.
797+
798+ This FAT support is not a file system in itself, it only provides
799+ the foundation for the other file systems. You will have to say Y or
800+ M to at least one of "MSDOS fs support" or "VFAT fs support" in
801+ order to make use of it.
802+
803+ Another way to read and write MSDOS floppies and hard drive
804+ partitions from within Linux (but not transparently) is with the
805+ mtools ("man mtools") program suite. You don't need to say Y here in
806+ order to do that.
807+
808+ If you need to move large files on floppies between a DOS and a
809+ Linux box, say Y here, mount the floppy under Linux with an MSDOS
810+ file system and use GNU tar's M option. GNU tar is a program
811+ available for Unix and DOS ("man tar" or "info tar").
812+
813+ The FAT support will enlarge your kernel by about 37 KB. If unsure,
814+ say Y.
815+
816+ To compile this as a module, choose M here: the module will be called
817+ fat. Note that if you compile the FAT support as a module, you
818+ cannot compile any of the FAT-based file systems into the kernel
819+ -- they will have to be modules as well.
820+
821+config MSDOS_FS
822+ tristate "MSDOS fs support"
823+ select FAT_FS
824+ help
825+ This allows you to mount MSDOS partitions of your hard drive (unless
826+ they are compressed; to access compressed MSDOS partitions under
827+ Linux, you can either use the DOS emulator DOSEMU, described in the
828+ DOSEMU-HOWTO, available from
829+ <http://www.tldp.org/docs.html#howto>, or try dmsdosfs in
830+ <ftp://ibiblio.org/pub/Linux/system/filesystems/dosfs/>. If you
831+ intend to use dosemu with a non-compressed MSDOS partition, say Y
832+ here) and MSDOS floppies. This means that file access becomes
833+ transparent, i.e. the MSDOS files look and behave just like all
834+ other Unix files.
835+
836+ If you have Windows 95 or Windows NT installed on your MSDOS
837+ partitions, you should use the VFAT file system (say Y to "VFAT fs
838+ support" below), or you will not be able to see the long filenames
839+ generated by Windows 95 / Windows NT.
840+
841+ This option will enlarge your kernel by about 7 KB. If unsure,
842+ answer Y. This will only work if you said Y to "DOS FAT fs support"
843+ as well. To compile this as a module, choose M here: the module will
844+ be called msdos.
845+
846+config VFAT_FS
847+ tristate "VFAT (Windows-95) fs support"
848+ select FAT_FS
849+ help
850+ This option provides support for normal Windows file systems with
851+ long filenames. That includes non-compressed FAT-based file systems
852+ used by Windows 95, Windows 98, Windows NT 4.0, and the Unix
853+ programs from the mtools package.
854+
855+ The VFAT support enlarges your kernel by about 10 KB and it only
856+ works if you said Y to the "DOS FAT fs support" above. Please read
857+ the file <file:Documentation/filesystems/vfat.txt> for details. If
858+ unsure, say Y.
859+
860+ To compile this as a module, choose M here: the module will be called
861+ vfat.
862+
863+config FAT_DEFAULT_CODEPAGE
864+ int "Default codepage for FAT"
865+ depends on MSDOS_FS || VFAT_FS
866+ default 437
867+ help
868+ This option should be set to the codepage of your FAT filesystems.
869+ It can be overridden with the "codepage" mount option.
870+ See <file:Documentation/filesystems/vfat.txt> for more information.
871+
872+config FAT_DEFAULT_IOCHARSET
873+ string "Default iocharset for FAT"
874+ depends on VFAT_FS
875+ default "iso8859-1"
876+ help
877+ Set this to the default input/output character set you'd
878+ like FAT to use. It should probably match the character set
879+ that most of your FAT filesystems use, and can be overridden
880+ with the "iocharset" mount option for FAT filesystems.
881+ Note that "utf8" is not recommended for FAT filesystems.
882+ If unsure, you shouldn't set "utf8" here.
883+ See <file:Documentation/filesystems/vfat.txt> for more information.
884+
885+config NTFS_FS
886+ tristate "NTFS file system support"
887+ select NLS
888+ help
889+ NTFS is the file system of Microsoft Windows NT, 2000, XP and 2003.
890+
891+ Saying Y or M here enables read support. There is partial, but
892+ safe, write support available. For write support you must also
893+ say Y to "NTFS write support" below.
894+
895+ There are also a number of user-space tools available, called
896+ ntfsprogs. These include ntfsundelete and ntfsresize, that work
897+ without NTFS support enabled in the kernel.
898+
899+ This is a rewrite from scratch of Linux NTFS support and replaced
900+ the old NTFS code starting with Linux 2.5.11. A backport to
901+ the Linux 2.4 kernel series is separately available as a patch
902+ from the project web site.
903+
904+ For more information see <file:Documentation/filesystems/ntfs.txt>
905+ and <http://www.linux-ntfs.org/>.
906+
907+ To compile this file system support as a module, choose M here: the
908+ module will be called ntfs.
909+
910+ If you are not using Windows NT, 2000, XP or 2003 in addition to
911+ Linux on your computer it is safe to say N.
912+
913+config NTFS_DEBUG
914+ bool "NTFS debugging support"
915+ depends on NTFS_FS
916+ help
917+ If you are experiencing any problems with the NTFS file system, say
918+ Y here. This will result in additional consistency checks to be
919+ performed by the driver as well as additional debugging messages to
920+ be written to the system log. Note that debugging messages are
921+ disabled by default. To enable them, supply the option debug_msgs=1
922+ at the kernel command line when booting the kernel or as an option
923+ to insmod when loading the ntfs module. Once the driver is active,
924+ you can enable debugging messages by doing (as root):
925+ echo 1 > /proc/sys/fs/ntfs-debug
926+ Replacing the "1" with "0" would disable debug messages.
927+
928+ If you leave debugging messages disabled, this results in little
929+ overhead, but enabling debug messages results in very significant
930+ slowdown of the system.
931+
932+ When reporting bugs, please try to have available a full dump of
933+ debugging messages while the misbehaviour was occurring.
934+
935+config NTFS_RW
936+ bool "NTFS write support"
937+ depends on NTFS_FS
938+ help
939+ This enables the partial, but safe, write support in the NTFS driver.
940+
941+ The only supported operation is overwriting existing files, without
942+ changing the file length. No file or directory creation, deletion or
943+ renaming is possible. Note only non-resident files can be written to
944+ so you may find that some very small files (<500 bytes or so) cannot
945+ be written to.
946+
947+ While we cannot guarantee that it will not damage any data, we have
948+ so far not received a single report where the driver would have
949+ damaged someones data so we assume it is perfectly safe to use.
950+
951+ Note: While write support is safe in this version (a rewrite from
952+ scratch of the NTFS support), it should be noted that the old NTFS
953+ write support, included in Linux 2.5.10 and before (since 1997),
954+ is not safe.
955+
956+ This is currently useful with TopologiLinux. TopologiLinux is run
957+ on top of any DOS/Microsoft Windows system without partitioning your
958+ hard disk. Unlike other Linux distributions TopologiLinux does not
959+ need its own partition. For more information see
960+ <http://topologi-linux.sourceforge.net/>
961+
962+ It is perfectly safe to say N here.
963+
964+endmenu
965+endif # BLOCK
966+
967+menu "Pseudo filesystems"
968+
969+source "fs/proc/Kconfig"
970+
971+config SYSFS
972+ bool "sysfs file system support" if EMBEDDED
973+ default y
974+ help
975+ The sysfs filesystem is a virtual filesystem that the kernel uses to
976+ export internal kernel objects, their attributes, and their
977+ relationships to one another.
978+
979+ Users can use sysfs to ascertain useful information about the running
980+ kernel, such as the devices the kernel has discovered on each bus and
981+ which driver each is bound to. sysfs can also be used to tune devices
982+ and other kernel subsystems.
983+
984+ Some system agents rely on the information in sysfs to operate.
985+ /sbin/hotplug uses device and object attributes in sysfs to assist in
986+ delegating policy decisions, like persistently naming devices.
987+
988+ sysfs is currently used by the block subsystem to mount the root
989+ partition. If sysfs is disabled you must specify the boot device on
990+ the kernel boot command line via its major and minor numbers. For
991+ example, "root=03:01" for /dev/hda1.
992+
993+ Designers of embedded systems may wish to say N here to conserve space.
994+
995+config TMPFS
996+ bool "Virtual memory file system support (former shm fs)"
997+ help
998+ Tmpfs is a file system which keeps all files in virtual memory.
999+
1000+ Everything in tmpfs is temporary in the sense that no files will be
1001+ created on your hard drive. The files live in memory and swap
1002+ space. If you unmount a tmpfs instance, everything stored therein is
1003+ lost.
1004+
1005+ See <file:Documentation/filesystems/tmpfs.txt> for details.
1006+
1007+config TMPFS_POSIX_ACL
1008+ bool "Tmpfs POSIX Access Control Lists"
1009+ depends on TMPFS
1010+ select GENERIC_ACL
1011+ help
1012+ POSIX Access Control Lists (ACLs) support permissions for users and
1013+ groups beyond the owner/group/world scheme.
1014+
1015+ To learn more about Access Control Lists, visit the POSIX ACLs for
1016+ Linux website <http://acl.bestbits.at/>.
1017+
1018+ If you don't know what Access Control Lists are, say N.
1019+
1020+config HUGETLBFS
1021+ bool "HugeTLB file system support"
1022+ depends on X86 || IA64 || PPC64 || SPARC64 || (SUPERH && MMU) || \
1023+ (S390 && 64BIT) || BROKEN
1024+ help
1025+ hugetlbfs is a filesystem backing for HugeTLB pages, based on
1026+ ramfs. For architectures that support it, say Y here and read
1027+ <file:Documentation/vm/hugetlbpage.txt> for details.
1028+
1029+ If unsure, say N.
1030+
1031+config HUGETLB_PAGE
1032+ def_bool HUGETLBFS
1033+
1034+config CONFIGFS_FS
1035+ tristate "Userspace-driven configuration filesystem"
1036+ depends on SYSFS
1037+ help
1038+ configfs is a ram-based filesystem that provides the converse
1039+ of sysfs's functionality. Where sysfs is a filesystem-based
1040+ view of kernel objects, configfs is a filesystem-based manager
1041+ of kernel objects, or config_items.
1042+
1043+ Both sysfs and configfs can and should exist together on the
1044+ same system. One is not a replacement for the other.
1045+
1046+endmenu
1047+
1048+menu "Miscellaneous filesystems"
1049+
1050+config ADFS_FS
1051+ tristate "ADFS file system support (EXPERIMENTAL)"
1052+ depends on BLOCK && EXPERIMENTAL
1053+ help
1054+ The Acorn Disc Filing System is the standard file system of the
1055+ RiscOS operating system which runs on Acorn's ARM-based Risc PC
1056+ systems and the Acorn Archimedes range of machines. If you say Y
1057+ here, Linux will be able to read from ADFS partitions on hard drives
1058+ and from ADFS-formatted floppy discs. If you also want to be able to
1059+ write to those devices, say Y to "ADFS write support" below.
1060+
1061+ The ADFS partition should be the first partition (i.e.,
1062+ /dev/[hs]d?1) on each of your drives. Please read the file
1063+ <file:Documentation/filesystems/adfs.txt> for further details.
1064+
1065+ To compile this code as a module, choose M here: the module will be
1066+ called adfs.
1067+
1068+ If unsure, say N.
1069+
1070+config ADFS_FS_RW
1071+ bool "ADFS write support (DANGEROUS)"
1072+ depends on ADFS_FS
1073+ help
1074+ If you say Y here, you will be able to write to ADFS partitions on
1075+ hard drives and ADFS-formatted floppy disks. This is experimental
1076+ codes, so if you're unsure, say N.
1077+
1078+config AFFS_FS
1079+ tristate "Amiga FFS file system support (EXPERIMENTAL)"
1080+ depends on BLOCK && EXPERIMENTAL
1081+ help
1082+ The Fast File System (FFS) is the common file system used on hard
1083+ disks by Amiga(tm) systems since AmigaOS Version 1.3 (34.20). Say Y
1084+ if you want to be able to read and write files from and to an Amiga
1085+ FFS partition on your hard drive. Amiga floppies however cannot be
1086+ read with this driver due to an incompatibility of the floppy
1087+ controller used in an Amiga and the standard floppy controller in
1088+ PCs and workstations. Read <file:Documentation/filesystems/affs.txt>
1089+ and <file:fs/affs/Changes>.
1090+
1091+ With this driver you can also mount disk files used by Bernd
1092+ Schmidt's Un*X Amiga Emulator
1093+ (<http://www.freiburg.linux.de/~uae/>).
1094+ If you want to do this, you will also need to say Y or M to "Loop
1095+ device support", above.
1096+
1097+ To compile this file system support as a module, choose M here: the
1098+ module will be called affs. If unsure, say N.
1099+
1100+config ECRYPT_FS
1101+ tristate "eCrypt filesystem layer support (EXPERIMENTAL)"
1102+ depends on EXPERIMENTAL && KEYS && CRYPTO && NET
1103+ help
1104+ Encrypted filesystem that operates on the VFS layer. See
1105+ <file:Documentation/filesystems/ecryptfs.txt> to learn more about
1106+ eCryptfs. Userspace components are required and can be
1107+ obtained from <http://ecryptfs.sf.net>.
1108+
1109+ To compile this file system support as a module, choose M here: the
1110+ module will be called ecryptfs.
1111+
1112+config HFS_FS
1113+ tristate "Apple Macintosh file system support (EXPERIMENTAL)"
1114+ depends on BLOCK && EXPERIMENTAL
1115+ select NLS
1116+ help
1117+ If you say Y here, you will be able to mount Macintosh-formatted
1118+ floppy disks and hard drive partitions with full read-write access.
1119+ Please read <file:Documentation/filesystems/hfs.txt> to learn about
1120+ the available mount options.
1121+
1122+ To compile this file system support as a module, choose M here: the
1123+ module will be called hfs.
1124+
1125+config HFSPLUS_FS
1126+ tristate "Apple Extended HFS file system support"
1127+ depends on BLOCK
1128+ select NLS
1129+ select NLS_UTF8
1130+ help
1131+ If you say Y here, you will be able to mount extended format
1132+ Macintosh-formatted hard drive partitions with full read-write access.
1133+
1134+ This file system is often called HFS+ and was introduced with
1135+ MacOS 8. It includes all Mac specific filesystem data such as
1136+ data forks and creator codes, but it also has several UNIX
1137+ style features such as file ownership and permissions.
1138+
1139+config BEFS_FS
1140+ tristate "BeOS file system (BeFS) support (read only) (EXPERIMENTAL)"
1141+ depends on BLOCK && EXPERIMENTAL
1142+ select NLS
1143+ help
1144+ The BeOS File System (BeFS) is the native file system of Be, Inc's
1145+ BeOS. Notable features include support for arbitrary attributes
1146+ on files and directories, and database-like indices on selected
1147+ attributes. (Also note that this driver doesn't make those features
1148+ available at this time). It is a 64 bit filesystem, so it supports
1149+ extremely large volumes and files.
1150+
1151+ If you use this filesystem, you should also say Y to at least one
1152+ of the NLS (native language support) options below.
1153+
1154+ If you don't know what this is about, say N.
1155+
1156+ To compile this as a module, choose M here: the module will be
1157+ called befs.
1158+
1159+config BEFS_DEBUG
1160+ bool "Debug BeFS"
1161+ depends on BEFS_FS
1162+ help
1163+ If you say Y here, you can use the 'debug' mount option to enable
1164+ debugging output from the driver.
1165+
1166+config BFS_FS
1167+ tristate "BFS file system support (EXPERIMENTAL)"
1168+ depends on BLOCK && EXPERIMENTAL
1169+ help
1170+ Boot File System (BFS) is a file system used under SCO UnixWare to
1171+ allow the bootloader access to the kernel image and other important
1172+ files during the boot process. It is usually mounted under /stand
1173+ and corresponds to the slice marked as "STAND" in the UnixWare
1174+ partition. You should say Y if you want to read or write the files
1175+ on your /stand slice from within Linux. You then also need to say Y
1176+ to "UnixWare slices support", below. More information about the BFS
1177+ file system is contained in the file
1178+ <file:Documentation/filesystems/bfs.txt>.
1179+
1180+ If you don't know what this is about, say N.
1181+
1182+ To compile this as a module, choose M here: the module will be called
1183+ bfs. Note that the file system of your root partition (the one
1184+ containing the directory /) cannot be compiled as a module.
1185+
1186+
1187+
1188+config EFS_FS
1189+ tristate "EFS file system support (read only) (EXPERIMENTAL)"
1190+ depends on BLOCK && EXPERIMENTAL
1191+ help
1192+ EFS is an older file system used for non-ISO9660 CD-ROMs and hard
1193+ disk partitions by SGI's IRIX operating system (IRIX 6.0 and newer
1194+ uses the XFS file system for hard disk partitions however).
1195+
1196+ This implementation only offers read-only access. If you don't know
1197+ what all this is about, it's safe to say N. For more information
1198+ about EFS see its home page at <http://aeschi.ch.eu.org/efs/>.
1199+
1200+ To compile the EFS file system support as a module, choose M here: the
1201+ module will be called efs.
1202+
1203+config JFFS2_FS
1204+ tristate "Journalling Flash File System v2 (JFFS2) support"
1205+ select CRC32
1206+ depends on MTD
1207+ help
1208+ JFFS2 is the second generation of the Journalling Flash File System
1209+ for use on diskless embedded devices. It provides improved wear
1210+ levelling, compression and support for hard links. You cannot use
1211+ this on normal block devices, only on 'MTD' devices.
1212+
1213+ Further information on the design and implementation of JFFS2 is
1214+ available at <http://sources.redhat.com/jffs2/>.
1215+
1216+config JFFS2_FS_DEBUG
1217+ int "JFFS2 debugging verbosity (0 = quiet, 2 = noisy)"
1218+ depends on JFFS2_FS
1219+ default "0"
1220+ help
1221+ This controls the amount of debugging messages produced by the JFFS2
1222+ code. Set it to zero for use in production systems. For evaluation,
1223+ testing and debugging, it's advisable to set it to one. This will
1224+ enable a few assertions and will print debugging messages at the
1225+ KERN_DEBUG loglevel, where they won't normally be visible. Level 2
1226+ is unlikely to be useful - it enables extra debugging in certain
1227+ areas which at one point needed debugging, but when the bugs were
1228+ located and fixed, the detailed messages were relegated to level 2.
1229+
1230+ If reporting bugs, please try to have available a full dump of the
1231+ messages at debug level 1 while the misbehaviour was occurring.
1232+
1233+config JFFS2_FS_WRITEBUFFER
1234+ bool "JFFS2 write-buffering support"
1235+ depends on JFFS2_FS
1236+ default y
1237+ help
1238+ This enables the write-buffering support in JFFS2.
1239+
1240+ This functionality is required to support JFFS2 on the following
1241+ types of flash devices:
1242+ - NAND flash
1243+ - NOR flash with transparent ECC
1244+ - DataFlash
1245+
1246+config JFFS2_FS_WBUF_VERIFY
1247+ bool "Verify JFFS2 write-buffer reads"
1248+ depends on JFFS2_FS_WRITEBUFFER
1249+ default n
1250+ help
1251+ This causes JFFS2 to read back every page written through the
1252+ write-buffer, and check for errors.
1253+
1254+config JFFS2_SUMMARY
1255+ bool "JFFS2 summary support (EXPERIMENTAL)"
1256+ depends on JFFS2_FS && EXPERIMENTAL
1257+ default n
1258+ help
1259+ This feature makes it possible to use summary information
1260+ for faster filesystem mount.
1261+
1262+ The summary information can be inserted into a filesystem image
1263+ by the utility 'sumtool'.
1264+
1265+ If unsure, say 'N'.
1266+
1267+config JFFS2_FS_XATTR
1268+ bool "JFFS2 XATTR support (EXPERIMENTAL)"
1269+ depends on JFFS2_FS && EXPERIMENTAL
1270+ default n
1271+ help
1272+ Extended attributes are name:value pairs associated with inodes by
1273+ the kernel or by users (see the attr(5) manual page, or visit
1274+ <http://acl.bestbits.at/> for details).
1275+
1276+ If unsure, say N.
1277+
1278+config JFFS2_FS_POSIX_ACL
1279+ bool "JFFS2 POSIX Access Control Lists"
1280+ depends on JFFS2_FS_XATTR
1281+ default y
1282+ select FS_POSIX_ACL
1283+ help
1284+ Posix Access Control Lists (ACLs) support permissions for users and
1285+ groups beyond the owner/group/world scheme.
1286+
1287+ To learn more about Access Control Lists, visit the Posix ACLs for
1288+ Linux website <http://acl.bestbits.at/>.
1289+
1290+ If you don't know what Access Control Lists are, say N
1291+
1292+config JFFS2_FS_SECURITY
1293+ bool "JFFS2 Security Labels"
1294+ depends on JFFS2_FS_XATTR
1295+ default y
1296+ help
1297+ Security labels support alternative access control models
1298+ implemented by security modules like SELinux. This option
1299+ enables an extended attribute handler for file security
1300+ labels in the jffs2 filesystem.
1301+
1302+ If you are not using a security module that requires using
1303+ extended attributes for file security labels, say N.
1304+
1305+config JFFS2_COMPRESSION_OPTIONS
1306+ bool "Advanced compression options for JFFS2"
1307+ depends on JFFS2_FS
1308+ default n
1309+ help
1310+ Enabling this option allows you to explicitly choose which
1311+ compression modules, if any, are enabled in JFFS2. Removing
1312+ compressors can mean you cannot read existing file systems,
1313+ and enabling experimental compressors can mean that you
1314+ write a file system which cannot be read by a standard kernel.
1315+
1316+ If unsure, you should _definitely_ say 'N'.
1317+
1318+config JFFS2_ZLIB
1319+ bool "JFFS2 ZLIB compression support" if JFFS2_COMPRESSION_OPTIONS
1320+ select ZLIB_INFLATE
1321+ select ZLIB_DEFLATE
1322+ depends on JFFS2_FS
1323+ default y
1324+ help
1325+ Zlib is designed to be a free, general-purpose, legally unencumbered,
1326+ lossless data-compression library for use on virtually any computer
1327+ hardware and operating system. See <http://www.gzip.org/zlib/> for
1328+ further information.
1329+
1330+ Say 'Y' if unsure.
1331+
1332+config JFFS2_LZO
1333+ bool "JFFS2 LZO compression support" if JFFS2_COMPRESSION_OPTIONS
1334+ select LZO_COMPRESS
1335+ select LZO_DECOMPRESS
1336+ depends on JFFS2_FS
1337+ default n
1338+ help
1339+ minilzo-based compression. Generally works better than Zlib.
1340+
1341+ This feature was added in July, 2007. Say 'N' if you need
1342+ compatibility with older bootloaders or kernels.
1343+
1344+config JFFS2_RTIME
1345+ bool "JFFS2 RTIME compression support" if JFFS2_COMPRESSION_OPTIONS
1346+ depends on JFFS2_FS
1347+ default y
1348+ help
1349+ Rtime does manage to recompress already-compressed data. Say 'Y' if unsure.
1350+
1351+config JFFS2_RUBIN
1352+ bool "JFFS2 RUBIN compression support" if JFFS2_COMPRESSION_OPTIONS
1353+ depends on JFFS2_FS
1354+ default n
1355+ help
1356+ RUBINMIPS and DYNRUBIN compressors. Say 'N' if unsure.
1357+
1358+choice
1359+ prompt "JFFS2 default compression mode" if JFFS2_COMPRESSION_OPTIONS
1360+ default JFFS2_CMODE_PRIORITY
1361+ depends on JFFS2_FS
1362+ help
1363+ You can set here the default compression mode of JFFS2 from
1364+ the available compression modes. Don't touch if unsure.
1365+
1366+config JFFS2_CMODE_NONE
1367+ bool "no compression"
1368+ help
1369+ Uses no compression.
1370+
1371+config JFFS2_CMODE_PRIORITY
1372+ bool "priority"
1373+ help
1374+ Tries the compressors in a predefined order and chooses the first
1375+ successful one.
1376+
1377+config JFFS2_CMODE_SIZE
1378+ bool "size (EXPERIMENTAL)"
1379+ help
1380+ Tries all compressors and chooses the one which has the smallest
1381+ result.
1382+
1383+config JFFS2_CMODE_FAVOURLZO
1384+ bool "Favour LZO"
1385+ help
1386+ Tries all compressors and chooses the one which has the smallest
1387+ result but gives some preference to LZO (which has faster
1388+ decompression) at the expense of size.
1389+
1390+endchoice
1391+
1392+# UBIFS File system configuration
1393+source "fs/ubifs/Kconfig"
1394+
1395+config CRAMFS
1396+ tristate "Compressed ROM file system support (cramfs)"
1397+ depends on BLOCK
1398+ select ZLIB_INFLATE
1399+ help
1400+ Saying Y here includes support for CramFs (Compressed ROM File
1401+ System). CramFs is designed to be a simple, small, and compressed
1402+ file system for ROM based embedded systems. CramFs is read-only,
1403+ limited to 256MB file systems (with 16MB files), and doesn't support
1404+ 16/32 bits uid/gid, hard links and timestamps.
1405+
1406+ See <file:Documentation/filesystems/cramfs.txt> and
1407+ <file:fs/cramfs/README> for further information.
1408+
1409+ To compile this as a module, choose M here: the module will be called
1410+ cramfs. Note that the root file system (the one containing the
1411+ directory /) cannot be compiled as a module.
1412+
1413+ If unsure, say N.
1414+
1415+config VXFS_FS
1416+ tristate "FreeVxFS file system support (VERITAS VxFS(TM) compatible)"
1417+ depends on BLOCK
1418+ help
1419+ FreeVxFS is a file system driver that support the VERITAS VxFS(TM)
1420+ file system format. VERITAS VxFS(TM) is the standard file system
1421+ of SCO UnixWare (and possibly others) and optionally available
1422+ for Sunsoft Solaris, HP-UX and many other operating systems.
1423+ Currently only readonly access is supported.
1424+
1425+ NOTE: the file system type as used by mount(1), mount(2) and
1426+ fstab(5) is 'vxfs' as it describes the file system format, not
1427+ the actual driver.
1428+
1429+ To compile this as a module, choose M here: the module will be
1430+ called freevxfs. If unsure, say N.
1431+
1432+config MINIX_FS
1433+ tristate "Minix file system support"
1434+ depends on BLOCK
1435+ help
1436+ Minix is a simple operating system used in many classes about OS's.
1437+ The minix file system (method to organize files on a hard disk
1438+ partition or a floppy disk) was the original file system for Linux,
1439+ but has been superseded by the second extended file system ext2fs.
1440+ You don't want to use the minix file system on your hard disk
1441+ because of certain built-in restrictions, but it is sometimes found
1442+ on older Linux floppy disks. This option will enlarge your kernel
1443+ by about 28 KB. If unsure, say N.
1444+
1445+ To compile this file system support as a module, choose M here: the
1446+ module will be called minix. Note that the file system of your root
1447+ partition (the one containing the directory /) cannot be compiled as
1448+ a module.
1449+
1450+config OMFS_FS
1451+ tristate "SonicBlue Optimized MPEG File System support"
1452+ depends on BLOCK
1453+ select CRC_ITU_T
1454+ help
1455+ This is the proprietary file system used by the Rio Karma music
1456+ player and ReplayTV DVR. Despite the name, this filesystem is not
1457+ more efficient than a standard FS for MPEG files, in fact likely
1458+ the opposite is true. Say Y if you have either of these devices
1459+ and wish to mount its disk.
1460+
1461+ To compile this file system support as a module, choose M here: the
1462+ module will be called omfs. If unsure, say N.
1463+
1464+config HPFS_FS
1465+ tristate "OS/2 HPFS file system support"
1466+ depends on BLOCK
1467+ help
1468+ OS/2 is IBM's operating system for PC's, the same as Warp, and HPFS
1469+ is the file system used for organizing files on OS/2 hard disk
1470+ partitions. Say Y if you want to be able to read files from and
1471+ write files to an OS/2 HPFS partition on your hard drive. OS/2
1472+ floppies however are in regular MSDOS format, so you don't need this
1473+ option in order to be able to read them. Read
1474+ <file:Documentation/filesystems/hpfs.txt>.
1475+
1476+ To compile this file system support as a module, choose M here: the
1477+ module will be called hpfs. If unsure, say N.
1478+
1479+
1480+config QNX4FS_FS
1481+ tristate "QNX4 file system support (read only)"
1482+ depends on BLOCK
1483+ help
1484+ This is the file system used by the real-time operating systems
1485+ QNX 4 and QNX 6 (the latter is also called QNX RTP).
1486+ Further information is available at <http://www.qnx.com/>.
1487+ Say Y if you intend to mount QNX hard disks or floppies.
1488+ Unless you say Y to "QNX4FS read-write support" below, you will
1489+ only be able to read these file systems.
1490+
1491+ To compile this file system support as a module, choose M here: the
1492+ module will be called qnx4.
1493+
1494+ If you don't know whether you need it, then you don't need it:
1495+ answer N.
1496+
1497+config QNX4FS_RW
1498+ bool "QNX4FS write support (DANGEROUS)"
1499+ depends on QNX4FS_FS && EXPERIMENTAL && BROKEN
1500+ help
1501+ Say Y if you want to test write support for QNX4 file systems.
1502+
1503+ It's currently broken, so for now:
1504+ answer N.
1505+
1506+config ROMFS_FS
1507+ tristate "ROM file system support"
1508+ depends on BLOCK
1509+ ---help---
1510+ This is a very small read-only file system mainly intended for
1511+ initial ram disks of installation disks, but it could be used for
1512+ other read-only media as well. Read
1513+ <file:Documentation/filesystems/romfs.txt> for details.
1514+
1515+ To compile this file system support as a module, choose M here: the
1516+ module will be called romfs. Note that the file system of your
1517+ root partition (the one containing the directory /) cannot be a
1518+ module.
1519+
1520+ If you don't know whether you need it, then you don't need it:
1521+ answer N.
1522+
1523+
1524+config SYSV_FS
1525+ tristate "System V/Xenix/V7/Coherent file system support"
1526+ depends on BLOCK
1527+ help
1528+ SCO, Xenix and Coherent are commercial Unix systems for Intel
1529+ machines, and Version 7 was used on the DEC PDP-11. Saying Y
1530+ here would allow you to read from their floppies and hard disk
1531+ partitions.
1532+
1533+ If you have floppies or hard disk partitions like that, it is likely
1534+ that they contain binaries from those other Unix systems; in order
1535+ to run these binaries, you will want to install linux-abi which is
1536+ a set of kernel modules that lets you run SCO, Xenix, Wyse,
1537+ UnixWare, Dell Unix and System V programs under Linux. It is
1538+ available via FTP (user: ftp) from
1539+ <ftp://ftp.openlinux.org/pub/people/hch/linux-abi/>).
1540+ NOTE: that will work only for binaries from Intel-based systems;
1541+ PDP ones will have to wait until somebody ports Linux to -11 ;-)
1542+
1543+ If you only intend to mount files from some other Unix over the
1544+ network using NFS, you don't need the System V file system support
1545+ (but you need NFS file system support obviously).
1546+
1547+ Note that this option is generally not needed for floppies, since a
1548+ good portable way to transport files and directories between unixes
1549+ (and even other operating systems) is given by the tar program ("man
1550+ tar" or preferably "info tar"). Note also that this option has
1551+ nothing whatsoever to do with the option "System V IPC". Read about
1552+ the System V file system in
1553+ <file:Documentation/filesystems/sysv-fs.txt>.
1554+ Saying Y here will enlarge your kernel by about 27 KB.
1555+
1556+ To compile this as a module, choose M here: the module will be called
1557+ sysv.
1558+
1559+ If you haven't heard about all of this before, it's safe to say N.
1560+
1561+
1562+config UFS_FS
1563+ tristate "UFS file system support (read only)"
1564+ depends on BLOCK
1565+ help
1566+ BSD and derivate versions of Unix (such as SunOS, FreeBSD, NetBSD,
1567+ OpenBSD and NeXTstep) use a file system called UFS. Some System V
1568+ Unixes can create and mount hard disk partitions and diskettes using
1569+ this file system as well. Saying Y here will allow you to read from
1570+ these partitions; if you also want to write to them, say Y to the
1571+ experimental "UFS file system write support", below. Please read the
1572+ file <file:Documentation/filesystems/ufs.txt> for more information.
1573+
1574+ The recently released UFS2 variant (used in FreeBSD 5.x) is
1575+ READ-ONLY supported.
1576+
1577+ Note that this option is generally not needed for floppies, since a
1578+ good portable way to transport files and directories between unixes
1579+ (and even other operating systems) is given by the tar program ("man
1580+ tar" or preferably "info tar").
1581+
1582+ When accessing NeXTstep files, you may need to convert them from the
1583+ NeXT character set to the Latin1 character set; use the program
1584+ recode ("info recode") for this purpose.
1585+
1586+ To compile the UFS file system support as a module, choose M here: the
1587+ module will be called ufs.
1588+
1589+ If you haven't heard about all of this before, it's safe to say N.
1590+
1591+config UFS_FS_WRITE
1592+ bool "UFS file system write support (DANGEROUS)"
1593+ depends on UFS_FS && EXPERIMENTAL
1594+ help
1595+ Say Y here if you want to try writing to UFS partitions. This is
1596+ experimental, so you should back up your UFS partitions beforehand.
1597+
1598+config UFS_DEBUG
1599+ bool "UFS debugging"
1600+ depends on UFS_FS
1601+ help
1602+ If you are experiencing any problems with the UFS filesystem, say
1603+ Y here. This will result in _many_ additional debugging messages to be
1604+ written to the system log.
1605+
1606+endmenu
1607+
1608+menuconfig NETWORK_FILESYSTEMS
1609+ bool "Network File Systems"
1610+ default y
1611+ depends on NET
1612+ ---help---
1613+ Say Y here to get to see options for network filesystems and
1614+ filesystem-related networking code, such as NFS daemon and
1615+ RPCSEC security modules.
1616+
1617+ This option alone does not add any kernel code.
1618+
1619+ If you say N, all options in this submenu will be skipped and
1620+ disabled; if unsure, say Y here.
1621+
1622+if NETWORK_FILESYSTEMS
1623+
1624+config NFS_FS
1625+ tristate "NFS client support"
1626+ depends on INET
1627+ select LOCKD
1628+ select SUNRPC
1629+ select NFS_ACL_SUPPORT if NFS_V3_ACL
1630+ help
1631+ Choose Y here if you want to access files residing on other
1632+ computers using Sun's Network File System protocol. To compile
1633+ this file system support as a module, choose M here: the module
1634+ will be called nfs.
1635+
1636+ To mount file systems exported by NFS servers, you also need to
1637+ install the user space mount.nfs command which can be found in
1638+ the Linux nfs-utils package, available from http://linux-nfs.org/.
1639+ Information about using the mount command is available in the
1640+ mount(8) man page. More detail about the Linux NFS client
1641+ implementation is available via the nfs(5) man page.
1642+
1643+ Below you can choose which versions of the NFS protocol are
1644+ available in the kernel to mount NFS servers. Support for NFS
1645+ version 2 (RFC 1094) is always available when NFS_FS is selected.
1646+
1647+ To configure a system which mounts its root file system via NFS
1648+ at boot time, say Y here, select "Kernel level IP
1649+ autoconfiguration" in the NETWORK menu, and select "Root file
1650+ system on NFS" below. You cannot compile this file system as a
1651+ module in this case.
1652+
1653+ If unsure, say N.
1654+
1655+config NFS_V3
1656+ bool "NFS client support for NFS version 3"
1657+ depends on NFS_FS
1658+ help
1659+ This option enables support for version 3 of the NFS protocol
1660+ (RFC 1813) in the kernel's NFS client.
1661+
1662+ If unsure, say Y.
1663+
1664+config NFS_V3_ACL
1665+ bool "NFS client support for the NFSv3 ACL protocol extension"
1666+ depends on NFS_V3
1667+ help
1668+ Some NFS servers support an auxiliary NFSv3 ACL protocol that
1669+ Sun added to Solaris but never became an official part of the
1670+ NFS version 3 protocol. This protocol extension allows
1671+ applications on NFS clients to manipulate POSIX Access Control
1672+ Lists on files residing on NFS servers. NFS servers enforce
1673+ ACLs on local files whether this protocol is available or not.
1674+
1675+ Choose Y here if your NFS server supports the Solaris NFSv3 ACL
1676+ protocol extension and you want your NFS client to allow
1677+ applications to access and modify ACLs on files on the server.
1678+
1679+ Most NFS servers don't support the Solaris NFSv3 ACL protocol
1680+ extension. You can choose N here or specify the "noacl" mount
1681+ option to prevent your NFS client from trying to use the NFSv3
1682+ ACL protocol.
1683+
1684+ If unsure, say N.
1685+
1686+config NFS_V4
1687+ bool "NFS client support for NFS version 4 (EXPERIMENTAL)"
1688+ depends on NFS_FS && EXPERIMENTAL
1689+ select RPCSEC_GSS_KRB5
1690+ help
1691+ This option enables support for version 4 of the NFS protocol
1692+ (RFC 3530) in the kernel's NFS client.
1693+
1694+ To mount NFS servers using NFSv4, you also need to install user
1695+ space programs which can be found in the Linux nfs-utils package,
1696+ available from http://linux-nfs.org/.
1697+
1698+ If unsure, say N.
1699+
1700+config ROOT_NFS
1701+ bool "Root file system on NFS"
1702+ depends on NFS_FS=y && IP_PNP
1703+ help
1704+ If you want your system to mount its root file system via NFS,
1705+ choose Y here. This is common practice for managing systems
1706+ without local permanent storage. For details, read
1707+ <file:Documentation/filesystems/nfsroot.txt>.
1708+
1709+ Most people say N here.
1710+
1711+config NFSD
1712+ tristate "NFS server support"
1713+ depends on INET
1714+ select LOCKD
1715+ select SUNRPC
1716+ select EXPORTFS
1717+ select NFS_ACL_SUPPORT if NFSD_V2_ACL
1718+ help
1719+ Choose Y here if you want to allow other computers to access
1720+ files residing on this system using Sun's Network File System
1721+ protocol. To compile the NFS server support as a module,
1722+ choose M here: the module will be called nfsd.
1723+
1724+ You may choose to use a user-space NFS server instead, in which
1725+ case you can choose N here.
1726+
1727+ To export local file systems using NFS, you also need to install
1728+ user space programs which can be found in the Linux nfs-utils
1729+ package, available from http://linux-nfs.org/. More detail about
1730+ the Linux NFS server implementation is available via the
1731+ exports(5) man page.
1732+
1733+ Below you can choose which versions of the NFS protocol are
1734+ available to clients mounting the NFS server on this system.
1735+ Support for NFS version 2 (RFC 1094) is always available when
1736+ CONFIG_NFSD is selected.
1737+
1738+ If unsure, say N.
1739+
1740+config NFSD_V2_ACL
1741+ bool
1742+ depends on NFSD
1743+
1744+config NFSD_V3
1745+ bool "NFS server support for NFS version 3"
1746+ depends on NFSD
1747+ help
1748+ This option enables support in your system's NFS server for
1749+ version 3 of the NFS protocol (RFC 1813).
1750+
1751+ If unsure, say Y.
1752+
1753+config NFSD_V3_ACL
1754+ bool "NFS server support for the NFSv3 ACL protocol extension"
1755+ depends on NFSD_V3
1756+ select NFSD_V2_ACL
1757+ help
1758+ Solaris NFS servers support an auxiliary NFSv3 ACL protocol that
1759+ never became an official part of the NFS version 3 protocol.
1760+ This protocol extension allows applications on NFS clients to
1761+ manipulate POSIX Access Control Lists on files residing on NFS
1762+ servers. NFS servers enforce POSIX ACLs on local files whether
1763+ this protocol is available or not.
1764+
1765+ This option enables support in your system's NFS server for the
1766+ NFSv3 ACL protocol extension allowing NFS clients to manipulate
1767+ POSIX ACLs on files exported by your system's NFS server. NFS
1768+ clients which support the Solaris NFSv3 ACL protocol can then
1769+ access and modify ACLs on your NFS server.
1770+
1771+ To store ACLs on your NFS server, you also need to enable ACL-
1772+ related CONFIG options for your local file systems of choice.
1773+
1774+ If unsure, say N.
1775+
1776+config NFSD_V4
1777+ bool "NFS server support for NFS version 4 (EXPERIMENTAL)"
1778+ depends on NFSD && PROC_FS && EXPERIMENTAL
1779+ select NFSD_V3
1780+ select FS_POSIX_ACL
1781+ select RPCSEC_GSS_KRB5
1782+ help
1783+ This option enables support in your system's NFS server for
1784+ version 4 of the NFS protocol (RFC 3530).
1785+
1786+ To export files using NFSv4, you need to install additional user
1787+ space programs which can be found in the Linux nfs-utils package,
1788+ available from http://linux-nfs.org/.
1789+
1790+ If unsure, say N.
1791+
1792+config LOCKD
1793+ tristate
1794+
1795+config LOCKD_V4
1796+ bool
1797+ depends on NFSD_V3 || NFS_V3
1798+ default y
1799+
1800+config EXPORTFS
1801+ tristate
1802+
1803+config NFS_ACL_SUPPORT
1804+ tristate
1805+ select FS_POSIX_ACL
1806+
1807+config NFS_COMMON
1808+ bool
1809+ depends on NFSD || NFS_FS
1810+ default y
1811+
1812+config SUNRPC
1813+ tristate
1814+
1815+config SUNRPC_GSS
1816+ tristate
1817+
1818+config SUNRPC_XPRT_RDMA
1819+ tristate
1820+ depends on SUNRPC && INFINIBAND && EXPERIMENTAL
1821+ default SUNRPC && INFINIBAND
1822+ help
1823+ This option enables an RPC client transport capability that
1824+ allows the NFS client to mount servers via an RDMA-enabled
1825+ transport.
1826+
1827+ To compile RPC client RDMA transport support as a module,
1828+ choose M here: the module will be called xprtrdma.
1829+
1830+ If unsure, say N.
1831+
1832+config RPCSEC_GSS_KRB5
1833+ tristate "Secure RPC: Kerberos V mechanism (EXPERIMENTAL)"
1834+ depends on SUNRPC && EXPERIMENTAL
1835+ select SUNRPC_GSS
1836+ select CRYPTO
1837+ select CRYPTO_MD5
1838+ select CRYPTO_DES
1839+ select CRYPTO_CBC
1840+ help
1841+ Choose Y here to enable Secure RPC using the Kerberos version 5
1842+ GSS-API mechanism (RFC 1964).
1843+
1844+ Secure RPC calls with Kerberos require an auxiliary user-space
1845+ daemon which may be found in the Linux nfs-utils package
1846+ available from http://linux-nfs.org/. In addition, user-space
1847+ Kerberos support should be installed.
1848+
1849+ If unsure, say N.
1850+
1851+config RPCSEC_GSS_SPKM3
1852+ tristate "Secure RPC: SPKM3 mechanism (EXPERIMENTAL)"
1853+ depends on SUNRPC && EXPERIMENTAL
1854+ select SUNRPC_GSS
1855+ select CRYPTO
1856+ select CRYPTO_MD5
1857+ select CRYPTO_DES
1858+ select CRYPTO_CAST5
1859+ select CRYPTO_CBC
1860+ help
1861+ Choose Y here to enable Secure RPC using the SPKM3 public key
1862+ GSS-API mechansim (RFC 2025).
1863+
1864+ Secure RPC calls with SPKM3 require an auxiliary userspace
1865+ daemon which may be found in the Linux nfs-utils package
1866+ available from http://linux-nfs.org/.
1867+
1868+ If unsure, say N.
1869+
1870+config SMB_FS
1871+ tristate "SMB file system support (OBSOLETE, please use CIFS)"
1872+ depends on INET
1873+ select NLS
1874+ help
1875+ SMB (Server Message Block) is the protocol Windows for Workgroups
1876+ (WfW), Windows 95/98, Windows NT and OS/2 Lan Manager use to share
1877+ files and printers over local networks. Saying Y here allows you to
1878+ mount their file systems (often called "shares" in this context) and
1879+ access them just like any other Unix directory. Currently, this
1880+ works only if the Windows machines use TCP/IP as the underlying
1881+ transport protocol, and not NetBEUI. For details, read
1882+ <file:Documentation/filesystems/smbfs.txt> and the SMB-HOWTO,
1883+ available from <http://www.tldp.org/docs.html#howto>.
1884+
1885+ Note: if you just want your box to act as an SMB *server* and make
1886+ files and printing services available to Windows clients (which need
1887+ to have a TCP/IP stack), you don't need to say Y here; you can use
1888+ the program SAMBA (available from <ftp://ftp.samba.org/pub/samba/>)
1889+ for that.
1890+
1891+ General information about how to connect Linux, Windows machines and
1892+ Macs is on the WWW at <http://www.eats.com/linux_mac_win.html>.
1893+
1894+ To compile the SMB support as a module, choose M here:
1895+ the module will be called smbfs. Most people say N, however.
1896+
1897+config SMB_NLS_DEFAULT
1898+ bool "Use a default NLS"
1899+ depends on SMB_FS
1900+ help
1901+ Enabling this will make smbfs use nls translations by default. You
1902+ need to specify the local charset (CONFIG_NLS_DEFAULT) in the nls
1903+ settings and you need to give the default nls for the SMB server as
1904+ CONFIG_SMB_NLS_REMOTE.
1905+
1906+ The nls settings can be changed at mount time, if your smbmount
1907+ supports that, using the codepage and iocharset parameters.
1908+
1909+ smbmount from samba 2.2.0 or later supports this.
1910+
1911+config SMB_NLS_REMOTE
1912+ string "Default Remote NLS Option"
1913+ depends on SMB_NLS_DEFAULT
1914+ default "cp437"
1915+ help
1916+ This setting allows you to specify a default value for which
1917+ codepage the server uses. If this field is left blank no
1918+ translations will be done by default. The local codepage/charset
1919+ default to CONFIG_NLS_DEFAULT.
1920+
1921+ The nls settings can be changed at mount time, if your smbmount
1922+ supports that, using the codepage and iocharset parameters.
1923+
1924+ smbmount from samba 2.2.0 or later supports this.
1925+
1926+config CIFS
1927+ tristate "CIFS support (advanced network filesystem, SMBFS successor)"
1928+ depends on INET
1929+ select NLS
1930+ help
1931+ This is the client VFS module for the Common Internet File System
1932+ (CIFS) protocol which is the successor to the Server Message Block
1933+ (SMB) protocol, the native file sharing mechanism for most early
1934+ PC operating systems. The CIFS protocol is fully supported by
1935+ file servers such as Windows 2000 (including Windows 2003, NT 4
1936+ and Windows XP) as well by Samba (which provides excellent CIFS
1937+ server support for Linux and many other operating systems). Limited
1938+ support for OS/2 and Windows ME and similar servers is provided as
1939+ well.
1940+
1941+ The cifs module provides an advanced network file system
1942+ client for mounting to CIFS compliant servers. It includes
1943+ support for DFS (hierarchical name space), secure per-user
1944+ session establishment via Kerberos or NTLM or NTLMv2,
1945+ safe distributed caching (oplock), optional packet
1946+ signing, Unicode and other internationalization improvements.
1947+ If you need to mount to Samba or Windows from this machine, say Y.
1948+
1949+config CIFS_STATS
1950+ bool "CIFS statistics"
1951+ depends on CIFS
1952+ help
1953+ Enabling this option will cause statistics for each server share
1954+ mounted by the cifs client to be displayed in /proc/fs/cifs/Stats
1955+
1956+config CIFS_STATS2
1957+ bool "Extended statistics"
1958+ depends on CIFS_STATS
1959+ help
1960+ Enabling this option will allow more detailed statistics on SMB
1961+ request timing to be displayed in /proc/fs/cifs/DebugData and also
1962+ allow optional logging of slow responses to dmesg (depending on the
1963+ value of /proc/fs/cifs/cifsFYI, see fs/cifs/README for more details).
1964+ These additional statistics may have a minor effect on performance
1965+ and memory utilization.
1966+
1967+ Unless you are a developer or are doing network performance analysis
1968+ or tuning, say N.
1969+
1970+config CIFS_WEAK_PW_HASH
1971+ bool "Support legacy servers which use weaker LANMAN security"
1972+ depends on CIFS
1973+ help
1974+ Modern CIFS servers including Samba and most Windows versions
1975+ (since 1997) support stronger NTLM (and even NTLMv2 and Kerberos)
1976+ security mechanisms. These hash the password more securely
1977+ than the mechanisms used in the older LANMAN version of the
1978+ SMB protocol but LANMAN based authentication is needed to
1979+ establish sessions with some old SMB servers.
1980+
1981+ Enabling this option allows the cifs module to mount to older
1982+ LANMAN based servers such as OS/2 and Windows 95, but such
1983+ mounts may be less secure than mounts using NTLM or more recent
1984+ security mechanisms if you are on a public network. Unless you
1985+ have a need to access old SMB servers (and are on a private
1986+ network) you probably want to say N. Even if this support
1987+ is enabled in the kernel build, LANMAN authentication will not be
1988+ used automatically. At runtime LANMAN mounts are disabled but
1989+ can be set to required (or optional) either in
1990+ /proc/fs/cifs (see fs/cifs/README for more detail) or via an
1991+ option on the mount command. This support is disabled by
1992+ default in order to reduce the possibility of a downgrade
1993+ attack.
1994+
1995+ If unsure, say N.
1996+
1997+config CIFS_XATTR
1998+ bool "CIFS extended attributes"
1999+ depends on CIFS
2000+ help
2001+ Extended attributes are name:value pairs associated with inodes by
2002+ the kernel or by users (see the attr(5) manual page, or visit
2003+ <http://acl.bestbits.at/> for details). CIFS maps the name of
2004+ extended attributes beginning with the user namespace prefix
2005+ to SMB/CIFS EAs. EAs are stored on Windows servers without the
2006+ user namespace prefix, but their names are seen by Linux cifs clients
2007+ prefaced by the user namespace prefix. The system namespace
2008+ (used by some filesystems to store ACLs) is not supported at
2009+ this time.
2010+
2011+ If unsure, say N.
2012+
2013+config CIFS_POSIX
2014+ bool "CIFS POSIX Extensions"
2015+ depends on CIFS_XATTR
2016+ help
2017+ Enabling this option will cause the cifs client to attempt to
2018+ negotiate a newer dialect with servers, such as Samba 3.0.5
2019+ or later, that optionally can handle more POSIX like (rather
2020+ than Windows like) file behavior. It also enables
2021+ support for POSIX ACLs (getfacl and setfacl) to servers
2022+ (such as Samba 3.10 and later) which can negotiate
2023+ CIFS POSIX ACL support. If unsure, say N.
2024+
2025+config CIFS_DEBUG2
2026+ bool "Enable additional CIFS debugging routines"
2027+ depends on CIFS
2028+ help
2029+ Enabling this option adds a few more debugging routines
2030+ to the cifs code which slightly increases the size of
2031+ the cifs module and can cause additional logging of debug
2032+ messages in some error paths, slowing performance. This
2033+ option can be turned off unless you are debugging
2034+ cifs problems. If unsure, say N.
2035+
2036+config CIFS_EXPERIMENTAL
2037+ bool "CIFS Experimental Features (EXPERIMENTAL)"
2038+ depends on CIFS && EXPERIMENTAL
2039+ help
2040+ Enables cifs features under testing. These features are
2041+ experimental and currently include DFS support and directory
2042+ change notification ie fcntl(F_DNOTIFY), as well as the upcall
2043+ mechanism which will be used for Kerberos session negotiation
2044+ and uid remapping. Some of these features also may depend on
2045+ setting a value of 1 to the pseudo-file /proc/fs/cifs/Experimental
2046+ (which is disabled by default). See the file fs/cifs/README
2047+ for more details. If unsure, say N.
2048+
2049+config CIFS_UPCALL
2050+ bool "Kerberos/SPNEGO advanced session setup (EXPERIMENTAL)"
2051+ depends on CIFS_EXPERIMENTAL
2052+ depends on KEYS
2053+ help
2054+ Enables an upcall mechanism for CIFS which accesses
2055+ userspace helper utilities to provide SPNEGO packaged (RFC 4178)
2056+ Kerberos tickets which are needed to mount to certain secure servers
2057+ (for which more secure Kerberos authentication is required). If
2058+ unsure, say N.
2059+
2060+config CIFS_DFS_UPCALL
2061+ bool "DFS feature support (EXPERIMENTAL)"
2062+ depends on CIFS_EXPERIMENTAL
2063+ depends on KEYS
2064+ help
2065+ Enables an upcall mechanism for CIFS which contacts userspace
2066+ helper utilities to provide server name resolution (host names to
2067+ IP addresses) which is needed for implicit mounts of DFS junction
2068+ points. If unsure, say N.
2069+
2070+config NCP_FS
2071+ tristate "NCP file system support (to mount NetWare volumes)"
2072+ depends on IPX!=n || INET
2073+ help
2074+ NCP (NetWare Core Protocol) is a protocol that runs over IPX and is
2075+ used by Novell NetWare clients to talk to file servers. It is to
2076+ IPX what NFS is to TCP/IP, if that helps. Saying Y here allows you
2077+ to mount NetWare file server volumes and to access them just like
2078+ any other Unix directory. For details, please read the file
2079+ <file:Documentation/filesystems/ncpfs.txt> in the kernel source and
2080+ the IPX-HOWTO from <http://www.tldp.org/docs.html#howto>.
2081+
2082+ You do not have to say Y here if you want your Linux box to act as a
2083+ file *server* for Novell NetWare clients.
2084+
2085+ General information about how to connect Linux, Windows machines and
2086+ Macs is on the WWW at <http://www.eats.com/linux_mac_win.html>.
2087+
2088+ To compile this as a module, choose M here: the module will be called
2089+ ncpfs. Say N unless you are connected to a Novell network.
2090+
2091+source "fs/ncpfs/Kconfig"
2092+
2093+config CODA_FS
2094+ tristate "Coda file system support (advanced network fs)"
2095+ depends on INET
2096+ help
2097+ Coda is an advanced network file system, similar to NFS in that it
2098+ enables you to mount file systems of a remote server and access them
2099+ with regular Unix commands as if they were sitting on your hard
2100+ disk. Coda has several advantages over NFS: support for
2101+ disconnected operation (e.g. for laptops), read/write server
2102+ replication, security model for authentication and encryption,
2103+ persistent client caches and write back caching.
2104+
2105+ If you say Y here, your Linux box will be able to act as a Coda
2106+ *client*. You will need user level code as well, both for the
2107+ client and server. Servers are currently user level, i.e. they need
2108+ no kernel support. Please read
2109+ <file:Documentation/filesystems/coda.txt> and check out the Coda
2110+ home page <http://www.coda.cs.cmu.edu/>.
2111+
2112+ To compile the coda client support as a module, choose M here: the
2113+ module will be called coda.
2114+
2115+config AFS_FS
2116+ tristate "Andrew File System support (AFS) (EXPERIMENTAL)"
2117+ depends on INET && EXPERIMENTAL
2118+ select AF_RXRPC
2119+ help
2120+ If you say Y here, you will get an experimental Andrew File System
2121+ driver. It currently only supports unsecured read-only AFS access.
2122+
2123+ See <file:Documentation/filesystems/afs.txt> for more information.
2124+
2125+ If unsure, say N.
2126+
2127+config AFS_DEBUG
2128+ bool "AFS dynamic debugging"
2129+ depends on AFS_FS
2130+ help
2131+ Say Y here to make runtime controllable debugging messages appear.
2132+
2133+ See <file:Documentation/filesystems/afs.txt> for more information.
2134+
2135+ If unsure, say N.
2136+
2137+config 9P_FS
2138+ tristate "Plan 9 Resource Sharing Support (9P2000) (Experimental)"
2139+ depends on INET && NET_9P && EXPERIMENTAL
2140+ help
2141+ If you say Y here, you will get experimental support for
2142+ Plan 9 resource sharing via the 9P2000 protocol.
2143+
2144+ See <http://v9fs.sf.net> for more information.
2145+
2146+ If unsure, say N.
2147+
2148+endif # NETWORK_FILESYSTEMS
2149+
2150+if BLOCK
2151+menu "Partition Types"
2152+
2153+source "fs/partitions/Kconfig"
2154+
2155+endmenu
2156+endif
2157+
2158+source "fs/nls/Kconfig"
2159+source "fs/dlm/Kconfig"
2160+
2161+endmenu
2162diff -uNr a/fs/Makefile b/fs/Makefile
2163--- a/fs/Makefile 2008-07-28 19:40:31.000000000 -0700
2164+++ b/fs/Makefile 2008-08-13 16:18:09.000000000 -0700
2165@@ -74,6 +74,7 @@
2166 obj-$(CONFIG_JBD2) += jbd2/
2167 obj-$(CONFIG_EXT2_FS) += ext2/
2168 obj-$(CONFIG_CRAMFS) += cramfs/
2169+obj-$(CONFIG_SQUASHFS) += squashfs/
2170 obj-y += ramfs/
2171 obj-$(CONFIG_HUGETLBFS) += hugetlbfs/
2172 obj-$(CONFIG_CODA_FS) += coda/
2173diff -uNr a/fs/squashfs/block.c b/fs/squashfs/block.c
2174--- a/fs/squashfs/block.c 1969-12-31 16:00:00.000000000 -0800
2175+++ b/fs/squashfs/block.c 2008-08-13 16:14:50.000000000 -0700
2176@@ -0,0 +1,314 @@
2177+/*
2178+ * Squashfs - a compressed read only filesystem for Linux
2179+ *
2180+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
2181+ * Phillip Lougher <phillip@lougher.demon.co.uk>
2182+ *
2183+ * This program is free software; you can redistribute it and/or
2184+ * modify it under the terms of the GNU General Public License
2185+ * as published by the Free Software Foundation; either version 2,
2186+ * or (at your option) any later version.
2187+ *
2188+ * This program is distributed in the hope that it will be useful,
2189+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2190+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2191+ * GNU General Public License for more details.
2192+ *
2193+ * You should have received a copy of the GNU General Public License
2194+ * along with this program; if not, write to the Free Software
2195+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
2196+ *
2197+ * block.c
2198+ */
2199+
2200+#include <linux/squashfs_fs.h>
2201+#include <linux/module.h>
2202+#include <linux/zlib.h>
2203+#include <linux/fs.h>
2204+#include <linux/squashfs_fs_sb.h>
2205+#include <linux/squashfs_fs_i.h>
2206+#include <linux/buffer_head.h>
2207+#include <linux/vfs.h>
2208+#include <linux/vmalloc.h>
2209+#include <linux/spinlock.h>
2210+#include <linux/smp_lock.h>
2211+#include <linux/exportfs.h>
2212+
2213+#include "squashfs.h"
2214+static struct buffer_head *get_block_length(struct super_block *s,
2215+ int *cur_index, int *offset, int *c_byte)
2216+{
2217+ struct squashfs_sb_info *msblk = s->s_fs_info;
2218+ unsigned short temp;
2219+ struct buffer_head *bh;
2220+
2221+ if (!(bh = sb_bread(s, *cur_index)))
2222+ goto out;
2223+
2224+ if (msblk->devblksize - *offset == 1) {
2225+ if (msblk->swap)
2226+ ((unsigned char *) &temp)[1] = *((unsigned char *)
2227+ (bh->b_data + *offset));
2228+ else
2229+ ((unsigned char *) &temp)[0] = *((unsigned char *)
2230+ (bh->b_data + *offset));
2231+ brelse(bh);
2232+ if (!(bh = sb_bread(s, ++(*cur_index))))
2233+ goto out;
2234+ if (msblk->swap)
2235+ ((unsigned char *) &temp)[0] = *((unsigned char *)
2236+ bh->b_data);
2237+ else
2238+ ((unsigned char *) &temp)[1] = *((unsigned char *)
2239+ bh->b_data);
2240+ *c_byte = temp;
2241+ *offset = 1;
2242+ } else {
2243+ if (msblk->swap) {
2244+ ((unsigned char *) &temp)[1] = *((unsigned char *)
2245+ (bh->b_data + *offset));
2246+ ((unsigned char *) &temp)[0] = *((unsigned char *)
2247+ (bh->b_data + *offset + 1));
2248+ } else {
2249+ ((unsigned char *) &temp)[0] = *((unsigned char *)
2250+ (bh->b_data + *offset));
2251+ ((unsigned char *) &temp)[1] = *((unsigned char *)
2252+ (bh->b_data + *offset + 1));
2253+ }
2254+ *c_byte = temp;
2255+ *offset += 2;
2256+ }
2257+
2258+ if (SQUASHFS_CHECK_DATA(msblk->sblk.flags)) {
2259+ if (*offset == msblk->devblksize) {
2260+ brelse(bh);
2261+ if (!(bh = sb_bread(s, ++(*cur_index))))
2262+ goto out;
2263+ *offset = 0;
2264+ }
2265+ if (*((unsigned char *) (bh->b_data + *offset)) !=
2266+ SQUASHFS_MARKER_BYTE) {
2267+ ERROR("Metadata block marker corrupt @ %x\n",
2268+ *cur_index);
2269+ brelse(bh);
2270+ goto out;
2271+ }
2272+ (*offset)++;
2273+ }
2274+ return bh;
2275+
2276+out:
2277+ return NULL;
2278+}
2279+
2280+
2281+unsigned int squashfs_read_data(struct super_block *s, char *buffer,
2282+ long long index, unsigned int length,
2283+ long long *next_index, int srclength)
2284+{
2285+ struct squashfs_sb_info *msblk = s->s_fs_info;
2286+ struct squashfs_super_block *sblk = &msblk->sblk;
2287+ struct buffer_head **bh;
2288+ unsigned int offset = index & ((1 << msblk->devblksize_log2) - 1);
2289+ unsigned int cur_index = index >> msblk->devblksize_log2;
2290+ int bytes, avail_bytes, b = 0, k = 0;
2291+ unsigned int compressed;
2292+ unsigned int c_byte = length;
2293+
2294+ bh = kmalloc(((sblk->block_size >> msblk->devblksize_log2) + 1) *
2295+ sizeof(struct buffer_head *), GFP_KERNEL);
2296+ if (bh == NULL)
2297+ goto read_failure;
2298+
2299+ if (c_byte) {
2300+ bytes = -offset;
2301+ compressed = SQUASHFS_COMPRESSED_BLOCK(c_byte);
2302+ c_byte = SQUASHFS_COMPRESSED_SIZE_BLOCK(c_byte);
2303+
2304+ TRACE("Block @ 0x%llx, %scompressed size %d, src size %d\n", index,
2305+ compressed ? "" : "un", (unsigned int) c_byte, srclength);
2306+
2307+ if (c_byte > srclength || index < 0 || (index + c_byte) > sblk->bytes_used)
2308+ goto read_failure;
2309+
2310+ for (b = 0; bytes < (int) c_byte; b++, cur_index++) {
2311+ bh[b] = sb_getblk(s, cur_index);
2312+ if (bh[b] == NULL)
2313+ goto block_release;
2314+ bytes += msblk->devblksize;
2315+ }
2316+ ll_rw_block(READ, b, bh);
2317+ } else {
2318+ if (index < 0 || (index + 2) > sblk->bytes_used)
2319+ goto read_failure;
2320+
2321+ bh[0] = get_block_length(s, &cur_index, &offset, &c_byte);
2322+ if (bh[0] == NULL)
2323+ goto read_failure;
2324+ b = 1;
2325+
2326+ bytes = msblk->devblksize - offset;
2327+ compressed = SQUASHFS_COMPRESSED(c_byte);
2328+ c_byte = SQUASHFS_COMPRESSED_SIZE(c_byte);
2329+
2330+ TRACE("Block @ 0x%llx, %scompressed size %d\n", index, compressed
2331+ ? "" : "un", (unsigned int) c_byte);
2332+
2333+ if (c_byte > srclength || (index + c_byte) > sblk->bytes_used)
2334+ goto block_release;
2335+
2336+ for (; bytes < c_byte; b++) {
2337+ bh[b] = sb_getblk(s, ++cur_index);
2338+ if (bh[b] == NULL)
2339+ goto block_release;
2340+ bytes += msblk->devblksize;
2341+ }
2342+ ll_rw_block(READ, b - 1, bh + 1);
2343+ }
2344+
2345+ if (compressed) {
2346+ int zlib_err = 0;
2347+
2348+ /*
2349+ * uncompress block
2350+ */
2351+
2352+ mutex_lock(&msblk->read_data_mutex);
2353+
2354+ msblk->stream.next_out = buffer;
2355+ msblk->stream.avail_out = srclength;
2356+
2357+ for (bytes = 0; k < b; k++) {
2358+ avail_bytes = min(c_byte - bytes, msblk->devblksize - offset);
2359+
2360+ wait_on_buffer(bh[k]);
2361+ if (!buffer_uptodate(bh[k]))
2362+ goto release_mutex;
2363+
2364+ msblk->stream.next_in = bh[k]->b_data + offset;
2365+ msblk->stream.avail_in = avail_bytes;
2366+
2367+ if (k == 0) {
2368+ zlib_err = zlib_inflateInit(&msblk->stream);
2369+ if (zlib_err != Z_OK) {
2370+ ERROR("zlib_inflateInit returned unexpected result 0x%x,"
2371+ " srclength %d\n", zlib_err, srclength);
2372+ goto release_mutex;
2373+ }
2374+
2375+ if (avail_bytes == 0) {
2376+ offset = 0;
2377+ brelse(bh[k]);
2378+ continue;
2379+ }
2380+ }
2381+
2382+ zlib_err = zlib_inflate(&msblk->stream, Z_NO_FLUSH);
2383+ if (zlib_err != Z_OK && zlib_err != Z_STREAM_END) {
2384+ ERROR("zlib_inflate returned unexpected result 0x%x,"
2385+ " srclength %d, avail_in %d, avail_out %d\n", zlib_err,
2386+ srclength, msblk->stream.avail_in, msblk->stream.avail_out);
2387+ goto release_mutex;
2388+ }
2389+
2390+ bytes += avail_bytes;
2391+ offset = 0;
2392+ brelse(bh[k]);
2393+ }
2394+
2395+ if (zlib_err != Z_STREAM_END)
2396+ goto release_mutex;
2397+
2398+ zlib_err = zlib_inflateEnd(&msblk->stream);
2399+ if (zlib_err != Z_OK) {
2400+ ERROR("zlib_inflateEnd returned unexpected result 0x%x,"
2401+ " srclength %d\n", zlib_err, srclength);
2402+ goto release_mutex;
2403+ }
2404+ bytes = msblk->stream.total_out;
2405+ mutex_unlock(&msblk->read_data_mutex);
2406+ } else {
2407+ int i;
2408+
2409+ for(i = 0; i < b; i++) {
2410+ wait_on_buffer(bh[i]);
2411+ if (!buffer_uptodate(bh[i]))
2412+ goto block_release;
2413+ }
2414+
2415+ for (bytes = 0; k < b; k++) {
2416+ avail_bytes = min(c_byte - bytes, msblk->devblksize - offset);
2417+
2418+ memcpy(buffer + bytes, bh[k]->b_data + offset, avail_bytes);
2419+ bytes += avail_bytes;
2420+ offset = 0;
2421+ brelse(bh[k]);
2422+ }
2423+ }
2424+
2425+ if (next_index)
2426+ *next_index = index + c_byte + (length ? 0 :
2427+ (SQUASHFS_CHECK_DATA(msblk->sblk.flags) ? 3 : 2));
2428+
2429+ kfree(bh);
2430+ return bytes;
2431+
2432+release_mutex:
2433+ mutex_unlock(&msblk->read_data_mutex);
2434+
2435+block_release:
2436+ for (; k < b; k++)
2437+ brelse(bh[k]);
2438+
2439+read_failure:
2440+ ERROR("sb_bread failed reading block 0x%x\n", cur_index);
2441+ kfree(bh);
2442+ return 0;
2443+}
2444+
2445+
2446+int squashfs_get_cached_block(struct super_block *s, void *buffer,
2447+ long long block, unsigned int offset,
2448+ int length, long long *next_block,
2449+ unsigned int *next_offset)
2450+{
2451+ struct squashfs_sb_info *msblk = s->s_fs_info;
2452+ int bytes, return_length = length;
2453+ struct squashfs_cache_entry *entry;
2454+
2455+ TRACE("Entered squashfs_get_cached_block [%llx:%x]\n", block, offset);
2456+
2457+ while (1) {
2458+ entry = squashfs_cache_get(s, msblk->block_cache, block, 0);
2459+ bytes = entry->length - offset;
2460+
2461+ if (entry->error || bytes < 1) {
2462+ return_length = 0;
2463+ goto finish;
2464+ } else if (bytes >= length) {
2465+ if (buffer)
2466+ memcpy(buffer, entry->data + offset, length);
2467+ if (entry->length - offset == length) {
2468+ *next_block = entry->next_index;
2469+ *next_offset = 0;
2470+ } else {
2471+ *next_block = block;
2472+ *next_offset = offset + length;
2473+ }
2474+ goto finish;
2475+ } else {
2476+ if (buffer) {
2477+ memcpy(buffer, entry->data + offset, bytes);
2478+ buffer = (char *) buffer + bytes;
2479+ }
2480+ block = entry->next_index;
2481+ squashfs_cache_put(msblk->block_cache, entry);
2482+ length -= bytes;
2483+ offset = 0;
2484+ }
2485+ }
2486+
2487+finish:
2488+ squashfs_cache_put(msblk->block_cache, entry);
2489+ return return_length;
2490+}
2491diff -uNr a/fs/squashfs/cache.c b/fs/squashfs/cache.c
2492--- a/fs/squashfs/cache.c 1969-12-31 16:00:00.000000000 -0800
2493+++ b/fs/squashfs/cache.c 2008-08-13 16:14:50.000000000 -0700
2494@@ -0,0 +1,189 @@
2495+/*
2496+ * Squashfs - a compressed read only filesystem for Linux
2497+ *
2498+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
2499+ * Phillip Lougher <phillip@lougher.demon.co.uk>
2500+ *
2501+ * This program is free software; you can redistribute it and/or
2502+ * modify it under the terms of the GNU General Public License
2503+ * as published by the Free Software Foundation; either version 2,
2504+ * or (at your option) any later version.
2505+ *
2506+ * This program is distributed in the hope that it will be useful,
2507+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2508+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2509+ * GNU General Public License for more details.
2510+ *
2511+ * You should have received a copy of the GNU General Public License
2512+ * along with this program; if not, write to the Free Software
2513+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
2514+ *
2515+ * cache.c
2516+ */
2517+
2518+#include <linux/squashfs_fs.h>
2519+#include <linux/module.h>
2520+#include <linux/zlib.h>
2521+#include <linux/fs.h>
2522+#include <linux/squashfs_fs_sb.h>
2523+#include <linux/squashfs_fs_i.h>
2524+#include <linux/buffer_head.h>
2525+#include <linux/vfs.h>
2526+#include <linux/vmalloc.h>
2527+#include <linux/spinlock.h>
2528+#include <linux/smp_lock.h>
2529+#include <linux/exportfs.h>
2530+
2531+#include "squashfs.h"
2532+struct squashfs_cache_entry *squashfs_cache_get(struct super_block *s,
2533+ struct squashfs_cache *cache, long long block, int length)
2534+{
2535+ int i, n;
2536+ struct squashfs_cache_entry *entry;
2537+
2538+ spin_lock(&cache->lock);
2539+
2540+ while (1) {
2541+ for (i = 0; i < cache->entries && cache->entry[i].block != block; i++);
2542+
2543+ if (i == cache->entries) {
2544+ if (cache->unused_blks == 0) {
2545+ cache->waiting ++;
2546+ spin_unlock(&cache->lock);
2547+ wait_event(cache->wait_queue, cache->unused_blks);
2548+ spin_lock(&cache->lock);
2549+ cache->waiting --;
2550+ continue;
2551+ }
2552+
2553+ i = cache->next_blk;
2554+ for (n = 0; n < cache->entries; n++) {
2555+ if (cache->entry[i].locked == 0)
2556+ break;
2557+ i = (i + 1) % cache->entries;
2558+ }
2559+
2560+ cache->next_blk = (i + 1) % cache->entries;
2561+ entry = &cache->entry[i];
2562+
2563+ cache->unused_blks --;
2564+ entry->block = block;
2565+ entry->locked = 1;
2566+ entry->pending = 1;
2567+ entry->waiting = 0;
2568+ entry->error = 0;
2569+ spin_unlock(&cache->lock);
2570+
2571+ entry->length = squashfs_read_data(s, entry->data,
2572+ block, length, &entry->next_index, cache->block_size);
2573+
2574+ spin_lock(&cache->lock);
2575+
2576+ if (entry->length == 0)
2577+ entry->error = 1;
2578+
2579+ entry->pending = 0;
2580+ spin_unlock(&cache->lock);
2581+ if (entry->waiting)
2582+ wake_up_all(&entry->wait_queue);
2583+ goto out;
2584+ }
2585+
2586+ entry = &cache->entry[i];
2587+ if (entry->locked == 0)
2588+ cache->unused_blks --;
2589+ entry->locked++;
2590+
2591+ if (entry->pending) {
2592+ entry->waiting ++;
2593+ spin_unlock(&cache->lock);
2594+ wait_event(entry->wait_queue, !entry->pending);
2595+ goto out;
2596+ }
2597+
2598+ spin_unlock(&cache->lock);
2599+ goto out;
2600+ }
2601+
2602+out:
2603+ TRACE("Got %s %d, start block %lld, locked %d, error %d\n", i,
2604+ cache->name, entry->block, entry->locked, entry->error);
2605+ if (entry->error)
2606+ ERROR("Unable to read %s cache entry [%llx]\n", cache->name, block);
2607+ return entry;
2608+}
2609+
2610+
2611+void squashfs_cache_put(struct squashfs_cache *cache,
2612+ struct squashfs_cache_entry *entry)
2613+{
2614+ spin_lock(&cache->lock);
2615+ entry->locked --;
2616+ if (entry->locked == 0) {
2617+ cache->unused_blks ++;
2618+ spin_unlock(&cache->lock);
2619+ if (cache->waiting)
2620+ wake_up(&cache->wait_queue);
2621+ } else
2622+ spin_unlock(&cache->lock);
2623+}
2624+
2625+
2626+void squashfs_cache_delete(struct squashfs_cache *cache)
2627+{
2628+ int i;
2629+
2630+ if (cache == NULL)
2631+ return;
2632+
2633+ for (i = 0; i < cache->entries; i++)
2634+ if (cache->entry[i].data) {
2635+ if (cache->use_vmalloc)
2636+ vfree(cache->entry[i].data);
2637+ else
2638+ kfree(cache->entry[i].data);
2639+ }
2640+
2641+ kfree(cache);
2642+}
2643+
2644+
2645+struct squashfs_cache *squashfs_cache_init(char *name, int entries,
2646+ int block_size, int use_vmalloc)
2647+{
2648+ int i;
2649+ struct squashfs_cache *cache = kzalloc(sizeof(struct squashfs_cache) +
2650+ entries * sizeof(struct squashfs_cache_entry), GFP_KERNEL);
2651+ if (cache == NULL) {
2652+ ERROR("Failed to allocate %s cache\n", name);
2653+ goto failed;
2654+ }
2655+
2656+ cache->next_blk = 0;
2657+ cache->unused_blks = entries;
2658+ cache->entries = entries;
2659+ cache->block_size = block_size;
2660+ cache->use_vmalloc = use_vmalloc;
2661+ cache->name = name;
2662+ cache->waiting = 0;
2663+ spin_lock_init(&cache->lock);
2664+ init_waitqueue_head(&cache->wait_queue);
2665+
2666+ for (i = 0; i < entries; i++) {
2667+ init_waitqueue_head(&cache->entry[i].wait_queue);
2668+ cache->entry[i].block = SQUASHFS_INVALID_BLK;
2669+ cache->entry[i].data = use_vmalloc ? vmalloc(block_size) :
2670+ kmalloc(block_size, GFP_KERNEL);
2671+ if (cache->entry[i].data == NULL) {
2672+ ERROR("Failed to allocate %s cache entry\n", name);
2673+ goto cleanup;
2674+ }
2675+ }
2676+
2677+ return cache;
2678+
2679+cleanup:
2680+ squashfs_cache_delete(cache);
2681+failed:
2682+ return NULL;
2683+}
2684diff -uNr a/fs/squashfs/dir.c b/fs/squashfs/dir.c
2685--- a/fs/squashfs/dir.c 1969-12-31 16:00:00.000000000 -0800
2686+++ b/fs/squashfs/dir.c 2008-08-13 16:14:50.000000000 -0700
2687@@ -0,0 +1,216 @@
2688+/*
2689+ * Squashfs - a compressed read only filesystem for Linux
2690+ *
2691+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
2692+ * Phillip Lougher <phillip@lougher.demon.co.uk>
2693+ *
2694+ * This program is free software; you can redistribute it and/or
2695+ * modify it under the terms of the GNU General Public License
2696+ * as published by the Free Software Foundation; either version 2,
2697+ * or (at your option) any later version.
2698+ *
2699+ * This program is distributed in the hope that it will be useful,
2700+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2701+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2702+ * GNU General Public License for more details.
2703+ *
2704+ * You should have received a copy of the GNU General Public License
2705+ * along with this program; if not, write to the Free Software
2706+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
2707+ *
2708+ * dir.c
2709+ */
2710+
2711+#include <linux/squashfs_fs.h>
2712+#include <linux/module.h>
2713+#include <linux/zlib.h>
2714+#include <linux/fs.h>
2715+#include <linux/squashfs_fs_sb.h>
2716+#include <linux/squashfs_fs_i.h>
2717+#include <linux/buffer_head.h>
2718+#include <linux/vfs.h>
2719+#include <linux/vmalloc.h>
2720+#include <linux/spinlock.h>
2721+#include <linux/smp_lock.h>
2722+#include <linux/exportfs.h>
2723+
2724+#include "squashfs.h"
2725+
2726+static const unsigned char squashfs_filetype_table[] = {
2727+ DT_UNKNOWN, DT_DIR, DT_REG, DT_LNK, DT_BLK, DT_CHR, DT_FIFO, DT_SOCK
2728+};
2729+
2730+static int get_dir_index_using_offset(struct super_block *s,
2731+ long long *next_block, unsigned int *next_offset,
2732+ long long index_start, unsigned int index_offset, int i_count,
2733+ long long f_pos)
2734+{
2735+ struct squashfs_sb_info *msblk = s->s_fs_info;
2736+ struct squashfs_super_block *sblk = &msblk->sblk;
2737+ int i, length = 0;
2738+ struct squashfs_dir_index index;
2739+
2740+ TRACE("Entered get_dir_index_using_offset, i_count %d, f_pos %d\n",
2741+ i_count, (unsigned int) f_pos);
2742+
2743+ f_pos -= 3;
2744+ if (f_pos == 0)
2745+ goto finish;
2746+
2747+ for (i = 0; i < i_count; i++) {
2748+ if (msblk->swap) {
2749+ struct squashfs_dir_index sindex;
2750+ squashfs_get_cached_block(s, &sindex, index_start, index_offset,
2751+ sizeof(sindex), &index_start, &index_offset);
2752+ SQUASHFS_SWAP_DIR_INDEX(&index, &sindex);
2753+ } else
2754+ squashfs_get_cached_block(s, &index, index_start, index_offset,
2755+ sizeof(index), &index_start, &index_offset);
2756+
2757+ if (index.index > f_pos)
2758+ break;
2759+
2760+ squashfs_get_cached_block(s, NULL, index_start, index_offset,
2761+ index.size + 1, &index_start, &index_offset);
2762+
2763+ length = index.index;
2764+ *next_block = index.start_block + sblk->directory_table_start;
2765+ }
2766+
2767+ *next_offset = (length + *next_offset) % SQUASHFS_METADATA_SIZE;
2768+
2769+finish:
2770+ return length + 3;
2771+}
2772+
2773+
2774+static int squashfs_readdir(struct file *file, void *dirent, filldir_t filldir)
2775+{
2776+ struct inode *i = file->f_dentry->d_inode;
2777+ struct squashfs_sb_info *msblk = i->i_sb->s_fs_info;
2778+ struct squashfs_super_block *sblk = &msblk->sblk;
2779+ long long next_block = SQUASHFS_I(i)->start_block +
2780+ sblk->directory_table_start;
2781+ int next_offset = SQUASHFS_I(i)->offset, length = 0, dir_count;
2782+ struct squashfs_dir_header dirh;
2783+ struct squashfs_dir_entry *dire;
2784+
2785+ TRACE("Entered squashfs_readdir [%llx:%x]\n", next_block, next_offset);
2786+
2787+ dire = kmalloc(sizeof(struct squashfs_dir_entry) +
2788+ SQUASHFS_NAME_LEN + 1, GFP_KERNEL);
2789+ if (dire == NULL) {
2790+ ERROR("Failed to allocate squashfs_dir_entry\n");
2791+ goto finish;
2792+ }
2793+
2794+ while(file->f_pos < 3) {
2795+ char *name;
2796+ int size, i_ino;
2797+
2798+ if(file->f_pos == 0) {
2799+ name = ".";
2800+ size = 1;
2801+ i_ino = i->i_ino;
2802+ } else {
2803+ name = "..";
2804+ size = 2;
2805+ i_ino = SQUASHFS_I(i)->u.s2.parent_inode;
2806+ }
2807+ TRACE("Calling filldir(%x, %s, %d, %d, %d, %d)\n",
2808+ (unsigned int) dirent, name, size, (int)
2809+ file->f_pos, i_ino, squashfs_filetype_table[1]);
2810+
2811+ if (filldir(dirent, name, size, file->f_pos, i_ino,
2812+ squashfs_filetype_table[1]) < 0) {
2813+ TRACE("Filldir returned less than 0\n");
2814+ goto finish;
2815+ }
2816+ file->f_pos += size;
2817+ }
2818+
2819+ length = get_dir_index_using_offset(i->i_sb, &next_block, &next_offset,
2820+ SQUASHFS_I(i)->u.s2.directory_index_start,
2821+ SQUASHFS_I(i)->u.s2.directory_index_offset,
2822+ SQUASHFS_I(i)->u.s2.directory_index_count, file->f_pos);
2823+
2824+ while (length < i_size_read(i)) {
2825+ /* read directory header */
2826+ if (msblk->swap) {
2827+ struct squashfs_dir_header sdirh;
2828+
2829+ if (!squashfs_get_cached_block(i->i_sb, &sdirh, next_block,
2830+ next_offset, sizeof(sdirh), &next_block, &next_offset))
2831+ goto failed_read;
2832+
2833+ length += sizeof(sdirh);
2834+ SQUASHFS_SWAP_DIR_HEADER(&dirh, &sdirh);
2835+ } else {
2836+ if (!squashfs_get_cached_block(i->i_sb, &dirh, next_block,
2837+ next_offset, sizeof(dirh), &next_block, &next_offset))
2838+ goto failed_read;
2839+
2840+ length += sizeof(dirh);
2841+ }
2842+
2843+ dir_count = dirh.count + 1;
2844+ while (dir_count--) {
2845+ if (msblk->swap) {
2846+ struct squashfs_dir_entry sdire;
2847+ if (!squashfs_get_cached_block(i->i_sb, &sdire, next_block,
2848+ next_offset, sizeof(sdire), &next_block, &next_offset))
2849+ goto failed_read;
2850+
2851+ length += sizeof(sdire);
2852+ SQUASHFS_SWAP_DIR_ENTRY(dire, &sdire);
2853+ } else {
2854+ if (!squashfs_get_cached_block(i->i_sb, dire, next_block,
2855+ next_offset, sizeof(*dire), &next_block, &next_offset))
2856+ goto failed_read;
2857+
2858+ length += sizeof(*dire);
2859+ }
2860+
2861+ if (!squashfs_get_cached_block(i->i_sb, dire->name, next_block,
2862+ next_offset, dire->size + 1, &next_block, &next_offset))
2863+ goto failed_read;
2864+
2865+ length += dire->size + 1;
2866+
2867+ if (file->f_pos >= length)
2868+ continue;
2869+
2870+ dire->name[dire->size + 1] = '\0';
2871+
2872+ TRACE("Calling filldir(%x, %s, %d, %d, %x:%x, %d, %d)\n",
2873+ (unsigned int) dirent, dire->name, dire->size + 1,
2874+ (int) file->f_pos, dirh.start_block, dire->offset,
2875+ dirh.inode_number + dire->inode_number,
2876+ squashfs_filetype_table[dire->type]);
2877+
2878+ if (filldir(dirent, dire->name, dire->size + 1, file->f_pos,
2879+ dirh.inode_number + dire->inode_number,
2880+ squashfs_filetype_table[dire->type]) < 0) {
2881+ TRACE("Filldir returned less than 0\n");
2882+ goto finish;
2883+ }
2884+ file->f_pos = length;
2885+ }
2886+ }
2887+
2888+finish:
2889+ kfree(dire);
2890+ return 0;
2891+
2892+failed_read:
2893+ ERROR("Unable to read directory block [%llx:%x]\n", next_block,
2894+ next_offset);
2895+ kfree(dire);
2896+ return 0;
2897+}
2898+
2899+
2900+const struct file_operations squashfs_dir_ops = {
2901+ .read = generic_read_dir,
2902+ .readdir = squashfs_readdir
2903+};
2904diff -uNr a/fs/squashfs/export.c b/fs/squashfs/export.c
2905--- a/fs/squashfs/export.c 1969-12-31 16:00:00.000000000 -0800
2906+++ b/fs/squashfs/export.c 2008-08-13 16:14:50.000000000 -0700
2907@@ -0,0 +1,171 @@
2908+/*
2909+ * Squashfs - a compressed read only filesystem for Linux
2910+ *
2911+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
2912+ * Phillip Lougher <phillip@lougher.demon.co.uk>
2913+ *
2914+ * This program is free software; you can redistribute it and/or
2915+ * modify it under the terms of the GNU General Public License
2916+ * as published by the Free Software Foundation; either version 2,
2917+ * or (at your option) any later version.
2918+ *
2919+ * This program is distributed in the hope that it will be useful,
2920+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2921+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2922+ * GNU General Public License for more details.
2923+ *
2924+ * You should have received a copy of the GNU General Public License
2925+ * along with this program; if not, write to the Free Software
2926+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
2927+ *
2928+ * export.c
2929+ */
2930+
2931+#include <linux/squashfs_fs.h>
2932+#include <linux/module.h>
2933+#include <linux/zlib.h>
2934+#include <linux/fs.h>
2935+#include <linux/squashfs_fs_sb.h>
2936+#include <linux/squashfs_fs_i.h>
2937+#include <linux/buffer_head.h>
2938+#include <linux/vfs.h>
2939+#include <linux/vmalloc.h>
2940+#include <linux/spinlock.h>
2941+#include <linux/smp_lock.h>
2942+#include <linux/exportfs.h>
2943+
2944+#include "squashfs.h"
2945+static squashfs_inode_t squashfs_inode_lookup(struct super_block *s, int ino)
2946+{
2947+ struct squashfs_sb_info *msblk = s->s_fs_info;
2948+ long long start = msblk->inode_lookup_table[SQUASHFS_LOOKUP_BLOCK(ino - 1)];
2949+ int offset = SQUASHFS_LOOKUP_BLOCK_OFFSET(ino - 1);
2950+ squashfs_inode_t inode;
2951+
2952+ TRACE("Entered squashfs_inode_lookup, inode_number = %d\n", ino);
2953+
2954+ if (msblk->swap) {
2955+ squashfs_inode_t sinode;
2956+
2957+ if (!squashfs_get_cached_block(s, &sinode, start, offset,
2958+ sizeof(sinode), &start, &offset))
2959+ goto out;
2960+ SQUASHFS_SWAP_INODE_T((&inode), &sinode);
2961+ } else if (!squashfs_get_cached_block(s, &inode, start, offset,
2962+ sizeof(inode), &start, &offset))
2963+ goto out;
2964+
2965+ TRACE("squashfs_inode_lookup, inode = 0x%llx\n", inode);
2966+
2967+ return inode;
2968+
2969+out:
2970+ return SQUASHFS_INVALID_BLK;
2971+}
2972+
2973+
2974+static struct dentry *squashfs_export_iget(struct super_block *s,
2975+ unsigned int inode_number)
2976+{
2977+ squashfs_inode_t inode;
2978+ struct inode *i;
2979+ struct dentry *dentry;
2980+
2981+ TRACE("Entered squashfs_export_iget\n");
2982+
2983+ inode = squashfs_inode_lookup(s, inode_number);
2984+ if(inode == SQUASHFS_INVALID_BLK) {
2985+ dentry = ERR_PTR(-ENOENT);
2986+ goto failure;
2987+ }
2988+
2989+ i = squashfs_iget(s, inode, inode_number);
2990+ if(i == NULL) {
2991+ dentry = ERR_PTR(-EACCES);
2992+ goto failure;
2993+ }
2994+
2995+ dentry = d_alloc_anon(i);
2996+ if (dentry == NULL) {
2997+ iput(i);
2998+ dentry = ERR_PTR(-ENOMEM);
2999+ }
3000+
3001+failure:
3002+ return dentry;
3003+}
3004+
3005+
3006+static struct dentry *squashfs_fh_to_dentry(struct super_block *s,
3007+ struct fid *fid, int fh_len, int fh_type)
3008+{
3009+ if((fh_type != FILEID_INO32_GEN && fh_type != FILEID_INO32_GEN_PARENT) ||
3010+ fh_len < 2)
3011+ return NULL;
3012+
3013+ return squashfs_export_iget(s, fid->i32.ino);
3014+}
3015+
3016+
3017+static struct dentry *squashfs_fh_to_parent(struct super_block *s,
3018+ struct fid *fid, int fh_len, int fh_type)
3019+{
3020+ if(fh_type != FILEID_INO32_GEN_PARENT || fh_len < 4)
3021+ return NULL;
3022+
3023+ return squashfs_export_iget(s, fid->i32.parent_ino);
3024+}
3025+
3026+
3027+static struct dentry *squashfs_get_parent(struct dentry *child)
3028+{
3029+ struct inode *i = child->d_inode;
3030+
3031+ TRACE("Entered squashfs_get_parent\n");
3032+
3033+ return squashfs_export_iget(i->i_sb, SQUASHFS_I(i)->u.s2.parent_inode);
3034+}
3035+
3036+
3037+int read_inode_lookup_table(struct super_block *s)
3038+{
3039+ struct squashfs_sb_info *msblk = s->s_fs_info;
3040+ struct squashfs_super_block *sblk = &msblk->sblk;
3041+ unsigned int length = SQUASHFS_LOOKUP_BLOCK_BYTES(sblk->inodes);
3042+
3043+ TRACE("In read_inode_lookup_table, length %d\n", length);
3044+
3045+ /* Allocate inode lookup table */
3046+ msblk->inode_lookup_table = kmalloc(length, GFP_KERNEL);
3047+ if (msblk->inode_lookup_table == NULL) {
3048+ ERROR("Failed to allocate inode lookup table\n");
3049+ return 0;
3050+ }
3051+
3052+ if (!squashfs_read_data(s, (char *) msblk->inode_lookup_table,
3053+ sblk->lookup_table_start, length |
3054+ SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, length)) {
3055+ ERROR("unable to read inode lookup table\n");
3056+ return 0;
3057+ }
3058+
3059+ if (msblk->swap) {
3060+ int i;
3061+ long long block;
3062+
3063+ for (i = 0; i < SQUASHFS_LOOKUP_BLOCKS(sblk->inodes); i++) {
3064+ SQUASHFS_SWAP_LOOKUP_BLOCKS((&block),
3065+ &msblk->inode_lookup_table[i], 1);
3066+ msblk->inode_lookup_table[i] = block;
3067+ }
3068+ }
3069+
3070+ return 1;
3071+}
3072+
3073+
3074+const struct export_operations squashfs_export_ops = {
3075+ .fh_to_dentry = squashfs_fh_to_dentry,
3076+ .fh_to_parent = squashfs_fh_to_parent,
3077+ .get_parent = squashfs_get_parent
3078+};
3079diff -uNr a/fs/squashfs/file.c b/fs/squashfs/file.c
3080--- a/fs/squashfs/file.c 1969-12-31 16:00:00.000000000 -0800
3081+++ b/fs/squashfs/file.c 2008-08-13 16:14:50.000000000 -0700
3082@@ -0,0 +1,430 @@
3083+/*
3084+ * Squashfs - a compressed read only filesystem for Linux
3085+ *
3086+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
3087+ * Phillip Lougher <phillip@lougher.demon.co.uk>
3088+ *
3089+ * This program is free software; you can redistribute it and/or
3090+ * modify it under the terms of the GNU General Public License
3091+ * as published by the Free Software Foundation; either version 2,
3092+ * or (at your option) any later version.
3093+ *
3094+ * This program is distributed in the hope that it will be useful,
3095+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3096+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3097+ * GNU General Public License for more details.
3098+ *
3099+ * You should have received a copy of the GNU General Public License
3100+ * along with this program; if not, write to the Free Software
3101+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
3102+ *
3103+ * file.c
3104+ */
3105+
3106+#include <linux/squashfs_fs.h>
3107+#include <linux/module.h>
3108+#include <linux/zlib.h>
3109+#include <linux/fs.h>
3110+#include <linux/squashfs_fs_sb.h>
3111+#include <linux/squashfs_fs_i.h>
3112+#include <linux/buffer_head.h>
3113+#include <linux/vfs.h>
3114+#include <linux/vmalloc.h>
3115+#include <linux/spinlock.h>
3116+#include <linux/smp_lock.h>
3117+#include <linux/exportfs.h>
3118+
3119+#include "squashfs.h"
3120+
3121+static struct meta_index *locate_meta_index(struct inode *inode, int index, int offset)
3122+{
3123+ struct meta_index *meta = NULL;
3124+ struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info;
3125+ int i;
3126+
3127+ mutex_lock(&msblk->meta_index_mutex);
3128+
3129+ TRACE("locate_meta_index: index %d, offset %d\n", index, offset);
3130+
3131+ if (msblk->meta_index == NULL)
3132+ goto not_allocated;
3133+
3134+ for (i = 0; i < SQUASHFS_META_NUMBER; i ++) {
3135+ if (msblk->meta_index[i].inode_number == inode->i_ino &&
3136+ msblk->meta_index[i].offset >= offset &&
3137+ msblk->meta_index[i].offset <= index &&
3138+ msblk->meta_index[i].locked == 0) {
3139+ TRACE("locate_meta_index: entry %d, offset %d\n", i,
3140+ msblk->meta_index[i].offset);
3141+ meta = &msblk->meta_index[i];
3142+ offset = meta->offset;
3143+ }
3144+ }
3145+
3146+ if (meta)
3147+ meta->locked = 1;
3148+
3149+not_allocated:
3150+ mutex_unlock(&msblk->meta_index_mutex);
3151+
3152+ return meta;
3153+}
3154+
3155+
3156+static struct meta_index *empty_meta_index(struct inode *inode, int offset, int skip)
3157+{
3158+ struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info;
3159+ struct meta_index *meta = NULL;
3160+ int i;
3161+
3162+ mutex_lock(&msblk->meta_index_mutex);
3163+
3164+ TRACE("empty_meta_index: offset %d, skip %d\n", offset, skip);
3165+
3166+ if (msblk->meta_index == NULL) {
3167+ msblk->meta_index = kmalloc(sizeof(struct meta_index) *
3168+ SQUASHFS_META_NUMBER, GFP_KERNEL);
3169+ if (msblk->meta_index == NULL) {
3170+ ERROR("Failed to allocate meta_index\n");
3171+ goto failed;
3172+ }
3173+ for (i = 0; i < SQUASHFS_META_NUMBER; i++) {
3174+ msblk->meta_index[i].inode_number = 0;
3175+ msblk->meta_index[i].locked = 0;
3176+ }
3177+ msblk->next_meta_index = 0;
3178+ }
3179+
3180+ for (i = SQUASHFS_META_NUMBER; i &&
3181+ msblk->meta_index[msblk->next_meta_index].locked; i --)
3182+ msblk->next_meta_index = (msblk->next_meta_index + 1) %
3183+ SQUASHFS_META_NUMBER;
3184+
3185+ if (i == 0) {
3186+ TRACE("empty_meta_index: failed!\n");
3187+ goto failed;
3188+ }
3189+
3190+ TRACE("empty_meta_index: returned meta entry %d, %p\n",
3191+ msblk->next_meta_index,
3192+ &msblk->meta_index[msblk->next_meta_index]);
3193+
3194+ meta = &msblk->meta_index[msblk->next_meta_index];
3195+ msblk->next_meta_index = (msblk->next_meta_index + 1) %
3196+ SQUASHFS_META_NUMBER;
3197+
3198+ meta->inode_number = inode->i_ino;
3199+ meta->offset = offset;
3200+ meta->skip = skip;
3201+ meta->entries = 0;
3202+ meta->locked = 1;
3203+
3204+failed:
3205+ mutex_unlock(&msblk->meta_index_mutex);
3206+ return meta;
3207+}
3208+
3209+
3210+static void release_meta_index(struct inode *inode, struct meta_index *meta)
3211+{
3212+ meta->locked = 0;
3213+ smp_mb();
3214+}
3215+
3216+
3217+static int read_block_index(struct super_block *s, int blocks, char *block_list,
3218+ long long *start_block, int *offset)
3219+{
3220+ struct squashfs_sb_info *msblk = s->s_fs_info;
3221+ unsigned int *block_listp;
3222+ int block = 0;
3223+
3224+ if (msblk->swap) {
3225+ char sblock_list[blocks << 2];
3226+
3227+ if (!squashfs_get_cached_block(s, sblock_list, *start_block,
3228+ *offset, blocks << 2, start_block, offset)) {
3229+ ERROR("Fail reading block list [%llx:%x]\n", *start_block, *offset);
3230+ goto failure;
3231+ }
3232+ SQUASHFS_SWAP_INTS(((unsigned int *)block_list),
3233+ ((unsigned int *)sblock_list), blocks);
3234+ } else {
3235+ if (!squashfs_get_cached_block(s, block_list, *start_block,
3236+ *offset, blocks << 2, start_block, offset)) {
3237+ ERROR("Fail reading block list [%llx:%x]\n", *start_block, *offset);
3238+ goto failure;
3239+ }
3240+ }
3241+
3242+ for (block_listp = (unsigned int *) block_list; blocks;
3243+ block_listp++, blocks --)
3244+ block += SQUASHFS_COMPRESSED_SIZE_BLOCK(*block_listp);
3245+
3246+ return block;
3247+
3248+failure:
3249+ return -1;
3250+}
3251+
3252+
3253+#define SIZE 256
3254+
3255+static inline int calculate_skip(int blocks) {
3256+ int skip = (blocks - 1) / ((SQUASHFS_SLOTS * SQUASHFS_META_ENTRIES + 1) * SQUASHFS_META_INDEXES);
3257+ return skip >= 7 ? 7 : skip + 1;
3258+}
3259+
3260+
3261+static int get_meta_index(struct inode *inode, int index,
3262+ long long *index_block, int *index_offset,
3263+ long long *data_block, char *block_list)
3264+{
3265+ struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info;
3266+ struct squashfs_super_block *sblk = &msblk->sblk;
3267+ int skip = calculate_skip(i_size_read(inode) >> sblk->block_log);
3268+ int offset = 0;
3269+ struct meta_index *meta;
3270+ struct meta_entry *meta_entry;
3271+ long long cur_index_block = SQUASHFS_I(inode)->u.s1.block_list_start;
3272+ int cur_offset = SQUASHFS_I(inode)->offset;
3273+ long long cur_data_block = SQUASHFS_I(inode)->start_block;
3274+ int i;
3275+
3276+ index /= SQUASHFS_META_INDEXES * skip;
3277+
3278+ while (offset < index) {
3279+ meta = locate_meta_index(inode, index, offset + 1);
3280+
3281+ if (meta == NULL) {
3282+ meta = empty_meta_index(inode, offset + 1, skip);
3283+ if (meta == NULL)
3284+ goto all_done;
3285+ } else {
3286+ if(meta->entries == 0)
3287+ goto failed;
3288+ /* XXX */
3289+ offset = index < meta->offset + meta->entries ? index :
3290+ meta->offset + meta->entries - 1;
3291+ /* XXX */
3292+ meta_entry = &meta->meta_entry[offset - meta->offset];
3293+ cur_index_block = meta_entry->index_block + sblk->inode_table_start;
3294+ cur_offset = meta_entry->offset;
3295+ cur_data_block = meta_entry->data_block;
3296+ TRACE("get_meta_index: offset %d, meta->offset %d, "
3297+ "meta->entries %d\n", offset, meta->offset, meta->entries);
3298+ TRACE("get_meta_index: index_block 0x%llx, offset 0x%x"
3299+ " data_block 0x%llx\n", cur_index_block,
3300+ cur_offset, cur_data_block);
3301+ }
3302+
3303+ for (i = meta->offset + meta->entries; i <= index &&
3304+ i < meta->offset + SQUASHFS_META_ENTRIES; i++) {
3305+ int blocks = skip * SQUASHFS_META_INDEXES;
3306+
3307+ while (blocks) {
3308+ int block = blocks > (SIZE >> 2) ? (SIZE >> 2) : blocks;
3309+ int res = read_block_index(inode->i_sb, block, block_list,
3310+ &cur_index_block, &cur_offset);
3311+
3312+ if (res == -1)
3313+ goto failed;
3314+
3315+ cur_data_block += res;
3316+ blocks -= block;
3317+ }
3318+
3319+ meta_entry = &meta->meta_entry[i - meta->offset];
3320+ meta_entry->index_block = cur_index_block - sblk->inode_table_start;
3321+ meta_entry->offset = cur_offset;
3322+ meta_entry->data_block = cur_data_block;
3323+ meta->entries ++;
3324+ offset ++;
3325+ }
3326+
3327+ TRACE("get_meta_index: meta->offset %d, meta->entries %d\n",
3328+ meta->offset, meta->entries);
3329+
3330+ release_meta_index(inode, meta);
3331+ }
3332+
3333+all_done:
3334+ *index_block = cur_index_block;
3335+ *index_offset = cur_offset;
3336+ *data_block = cur_data_block;
3337+
3338+ return offset * SQUASHFS_META_INDEXES * skip;
3339+
3340+failed:
3341+ release_meta_index(inode, meta);
3342+ return -1;
3343+}
3344+
3345+
3346+long long read_blocklist(struct inode *inode, int index,
3347+ int readahead_blks, char *block_list,
3348+ unsigned short **block_p, unsigned int *bsize)
3349+{
3350+ long long block_ptr;
3351+ int offset;
3352+ long long block;
3353+ int res = get_meta_index(inode, index, &block_ptr, &offset, &block,
3354+ block_list);
3355+
3356+ TRACE("read_blocklist: res %d, index %d, block_ptr 0x%llx, offset"
3357+ " 0x%x, block 0x%llx\n", res, index, block_ptr, offset, block);
3358+
3359+ if(res == -1)
3360+ goto failure;
3361+
3362+ index -= res;
3363+
3364+ while (index) {
3365+ int blocks = index > (SIZE >> 2) ? (SIZE >> 2) : index;
3366+ int res = read_block_index(inode->i_sb, blocks, block_list,
3367+ &block_ptr, &offset);
3368+ if (res == -1)
3369+ goto failure;
3370+ block += res;
3371+ index -= blocks;
3372+ }
3373+
3374+ if (read_block_index(inode->i_sb, 1, block_list, &block_ptr, &offset) == -1)
3375+ goto failure;
3376+ *bsize = *((unsigned int *) block_list);
3377+
3378+ return block;
3379+
3380+failure:
3381+ return 0;
3382+}
3383+
3384+
3385+static int squashfs_readpage(struct file *file, struct page *page)
3386+{
3387+ struct inode *inode = page->mapping->host;
3388+ struct squashfs_sb_info *msblk = inode->i_sb->s_fs_info;
3389+ struct squashfs_super_block *sblk = &msblk->sblk;
3390+ unsigned char *block_list = NULL;
3391+ long long block;
3392+ unsigned int bsize, i;
3393+ int bytes;
3394+ int index = page->index >> (sblk->block_log - PAGE_CACHE_SHIFT);
3395+ void *pageaddr;
3396+ struct squashfs_cache_entry *fragment = NULL;
3397+ char *data_ptr = msblk->read_page;
3398+
3399+ int mask = (1 << (sblk->block_log - PAGE_CACHE_SHIFT)) - 1;
3400+ int start_index = page->index & ~mask;
3401+ int end_index = start_index | mask;
3402+ int file_end = i_size_read(inode) >> sblk->block_log;
3403+ int sparse = 0;
3404+
3405+ TRACE("Entered squashfs_readpage, page index %lx, start block %llx\n",
3406+ page->index, SQUASHFS_I(inode)->start_block);
3407+
3408+ if (page->index >= ((i_size_read(inode) + PAGE_CACHE_SIZE - 1) >>
3409+ PAGE_CACHE_SHIFT))
3410+ goto out;
3411+
3412+ if (SQUASHFS_I(inode)->u.s1.fragment_start_block == SQUASHFS_INVALID_BLK
3413+ || index < file_end) {
3414+ block_list = kmalloc(SIZE, GFP_KERNEL);
3415+ if (block_list == NULL) {
3416+ ERROR("Failed to allocate block_list\n");
3417+ goto error_out;
3418+ }
3419+
3420+ block = (msblk->read_blocklist)(inode, index, 1, block_list, NULL, &bsize);
3421+ if (block == 0)
3422+ goto error_out;
3423+
3424+ if (bsize == 0) { /* hole */
3425+ bytes = index == file_end ?
3426+ (i_size_read(inode) & (sblk->block_size - 1)) : sblk->block_size;
3427+ sparse = 1;
3428+ } else {
3429+ mutex_lock(&msblk->read_page_mutex);
3430+
3431+ bytes = squashfs_read_data(inode->i_sb, msblk->read_page, block,
3432+ bsize, NULL, sblk->block_size);
3433+
3434+ if (bytes == 0) {
3435+ ERROR("Unable to read page, block %llx, size %x\n", block, bsize);
3436+ mutex_unlock(&msblk->read_page_mutex);
3437+ goto error_out;
3438+ }
3439+ }
3440+ } else {
3441+ fragment = get_cached_fragment(inode->i_sb,
3442+ SQUASHFS_I(inode)-> u.s1.fragment_start_block,
3443+ SQUASHFS_I(inode)->u.s1.fragment_size);
3444+
3445+ if (fragment->error) {
3446+ ERROR("Unable to read page, block %llx, size %x\n",
3447+ SQUASHFS_I(inode)->u.s1.fragment_start_block,
3448+ (int) SQUASHFS_I(inode)->u.s1.fragment_size);
3449+ release_cached_fragment(msblk, fragment);
3450+ goto error_out;
3451+ }
3452+ bytes = i_size_read(inode) & (sblk->block_size - 1);
3453+ data_ptr = fragment->data + SQUASHFS_I(inode)->u.s1.fragment_offset;
3454+ }
3455+
3456+ for (i = start_index; i <= end_index && bytes > 0; i++,
3457+ bytes -= PAGE_CACHE_SIZE, data_ptr += PAGE_CACHE_SIZE) {
3458+ struct page *push_page;
3459+ int avail = sparse ? 0 : min_t(unsigned int, bytes, PAGE_CACHE_SIZE);
3460+
3461+ TRACE("bytes %d, i %d, available_bytes %d\n", bytes, i, avail);
3462+
3463+ push_page = (i == page->index) ? page :
3464+ grab_cache_page_nowait(page->mapping, i);
3465+
3466+ if (!push_page)
3467+ continue;
3468+
3469+ if (PageUptodate(push_page))
3470+ goto skip_page;
3471+
3472+ pageaddr = kmap_atomic(push_page, KM_USER0);
3473+ memcpy(pageaddr, data_ptr, avail);
3474+ memset(pageaddr + avail, 0, PAGE_CACHE_SIZE - avail);
3475+ kunmap_atomic(pageaddr, KM_USER0);
3476+ flush_dcache_page(push_page);
3477+ SetPageUptodate(push_page);
3478+skip_page:
3479+ unlock_page(push_page);
3480+ if(i != page->index)
3481+ page_cache_release(push_page);
3482+ }
3483+
3484+ if (SQUASHFS_I(inode)->u.s1.fragment_start_block == SQUASHFS_INVALID_BLK
3485+ || index < file_end) {
3486+ if (!sparse)
3487+ mutex_unlock(&msblk->read_page_mutex);
3488+ kfree(block_list);
3489+ } else
3490+ release_cached_fragment(msblk, fragment);
3491+
3492+ return 0;
3493+
3494+error_out:
3495+ SetPageError(page);
3496+out:
3497+ pageaddr = kmap_atomic(page, KM_USER0);
3498+ memset(pageaddr, 0, PAGE_CACHE_SIZE);
3499+ kunmap_atomic(pageaddr, KM_USER0);
3500+ flush_dcache_page(page);
3501+ if (!PageError(page))
3502+ SetPageUptodate(page);
3503+ unlock_page(page);
3504+
3505+ kfree(block_list);
3506+ return 0;
3507+}
3508+
3509+
3510+const struct address_space_operations squashfs_aops = {
3511+ .readpage = squashfs_readpage
3512+};
3513diff -uNr a/fs/squashfs/fragment.c b/fs/squashfs/fragment.c
3514--- a/fs/squashfs/fragment.c 1969-12-31 16:00:00.000000000 -0800
3515+++ b/fs/squashfs/fragment.c 2008-08-13 16:14:50.000000000 -0700
3516@@ -0,0 +1,122 @@
3517+/*
3518+ * Squashfs - a compressed read only filesystem for Linux
3519+ *
3520+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
3521+ * Phillip Lougher <phillip@lougher.demon.co.uk>
3522+ *
3523+ * This program is free software; you can redistribute it and/or
3524+ * modify it under the terms of the GNU General Public License
3525+ * as published by the Free Software Foundation; either version 2,
3526+ * or (at your option) any later version.
3527+ *
3528+ * This program is distributed in the hope that it will be useful,
3529+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3530+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3531+ * GNU General Public License for more details.
3532+ *
3533+ * You should have received a copy of the GNU General Public License
3534+ * along with this program; if not, write to the Free Software
3535+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
3536+ *
3537+ * fragment.c
3538+ */
3539+
3540+#include <linux/squashfs_fs.h>
3541+#include <linux/module.h>
3542+#include <linux/zlib.h>
3543+#include <linux/fs.h>
3544+#include <linux/squashfs_fs_sb.h>
3545+#include <linux/squashfs_fs_i.h>
3546+#include <linux/buffer_head.h>
3547+#include <linux/vfs.h>
3548+#include <linux/vmalloc.h>
3549+#include <linux/spinlock.h>
3550+#include <linux/smp_lock.h>
3551+#include <linux/exportfs.h>
3552+
3553+#include "squashfs.h"
3554+
3555+int get_fragment_location(struct super_block *s, unsigned int fragment,
3556+ long long *fragment_start_block,
3557+ unsigned int *fragment_size)
3558+{
3559+ struct squashfs_sb_info *msblk = s->s_fs_info;
3560+ long long start_block =
3561+ msblk->fragment_index[SQUASHFS_FRAGMENT_INDEX(fragment)];
3562+ int offset = SQUASHFS_FRAGMENT_INDEX_OFFSET(fragment);
3563+ struct squashfs_fragment_entry fragment_entry;
3564+
3565+ if (msblk->swap) {
3566+ struct squashfs_fragment_entry sfragment_entry;
3567+
3568+ if (!squashfs_get_cached_block(s, &sfragment_entry, start_block, offset,
3569+ sizeof(sfragment_entry), &start_block, &offset))
3570+ goto out;
3571+ SQUASHFS_SWAP_FRAGMENT_ENTRY(&fragment_entry, &sfragment_entry);
3572+ } else
3573+ if (!squashfs_get_cached_block(s, &fragment_entry, start_block, offset,
3574+ sizeof(fragment_entry), &start_block, &offset))
3575+ goto out;
3576+
3577+ *fragment_start_block = fragment_entry.start_block;
3578+ *fragment_size = fragment_entry.size;
3579+
3580+ return 1;
3581+
3582+out:
3583+ return 0;
3584+}
3585+
3586+
3587+void release_cached_fragment(struct squashfs_sb_info *msblk,
3588+ struct squashfs_cache_entry *fragment)
3589+{
3590+ squashfs_cache_put(msblk->fragment_cache, fragment);
3591+}
3592+
3593+
3594+struct squashfs_cache_entry *get_cached_fragment(struct super_block *s,
3595+ long long start_block, int length)
3596+{
3597+ struct squashfs_sb_info *msblk = s->s_fs_info;
3598+
3599+ return squashfs_cache_get(s, msblk->fragment_cache, start_block, length);
3600+}
3601+
3602+
3603+int read_fragment_index_table(struct super_block *s)
3604+{
3605+ struct squashfs_sb_info *msblk = s->s_fs_info;
3606+ struct squashfs_super_block *sblk = &msblk->sblk;
3607+ unsigned int length = SQUASHFS_FRAGMENT_INDEX_BYTES(sblk->fragments);
3608+
3609+ if(length == 0)
3610+ return 1;
3611+
3612+ /* Allocate fragment index table */
3613+ msblk->fragment_index = kmalloc(length, GFP_KERNEL);
3614+ if (msblk->fragment_index == NULL) {
3615+ ERROR("Failed to allocate fragment index table\n");
3616+ return 0;
3617+ }
3618+
3619+ if (!squashfs_read_data(s, (char *) msblk->fragment_index,
3620+ sblk->fragment_table_start, length |
3621+ SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, length)) {
3622+ ERROR("unable to read fragment index table\n");
3623+ return 0;
3624+ }
3625+
3626+ if (msblk->swap) {
3627+ int i;
3628+ long long fragment;
3629+
3630+ for (i = 0; i < SQUASHFS_FRAGMENT_INDEXES(sblk->fragments); i++) {
3631+ SQUASHFS_SWAP_FRAGMENT_INDEXES((&fragment),
3632+ &msblk->fragment_index[i], 1);
3633+ msblk->fragment_index[i] = fragment;
3634+ }
3635+ }
3636+
3637+ return 1;
3638+}
3639diff -uNr a/fs/squashfs/id.c b/fs/squashfs/id.c
3640--- a/fs/squashfs/id.c 1969-12-31 16:00:00.000000000 -0800
3641+++ b/fs/squashfs/id.c 2008-08-13 16:14:50.000000000 -0700
3642@@ -0,0 +1,97 @@
3643+/*
3644+ * Squashfs - a compressed read only filesystem for Linux
3645+ *
3646+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
3647+ * Phillip Lougher <phillip@lougher.demon.co.uk>
3648+ *
3649+ * This program is free software; you can redistribute it and/or
3650+ * modify it under the terms of the GNU General Public License
3651+ * as published by the Free Software Foundation; either version 2,
3652+ * or (at your option) any later version.
3653+ *
3654+ * This program is distributed in the hope that it will be useful,
3655+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3656+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3657+ * GNU General Public License for more details.
3658+ *
3659+ * You should have received a copy of the GNU General Public License
3660+ * along with this program; if not, write to the Free Software
3661+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
3662+ *
3663+ * id.c
3664+ */
3665+
3666+#include <linux/squashfs_fs.h>
3667+#include <linux/module.h>
3668+#include <linux/zlib.h>
3669+#include <linux/fs.h>
3670+#include <linux/squashfs_fs_sb.h>
3671+#include <linux/squashfs_fs_i.h>
3672+#include <linux/buffer_head.h>
3673+#include <linux/vfs.h>
3674+#include <linux/vmalloc.h>
3675+#include <linux/spinlock.h>
3676+#include <linux/smp_lock.h>
3677+#include <linux/exportfs.h>
3678+
3679+#include "squashfs.h"
3680+
3681+int get_id(struct super_block *s, unsigned int index, unsigned int *id)
3682+{
3683+ struct squashfs_sb_info *msblk = s->s_fs_info;
3684+ long long start_block = msblk->id_table[SQUASHFS_ID_BLOCK(index)];
3685+ int offset = SQUASHFS_ID_BLOCK_OFFSET(index);
3686+
3687+ if (msblk->swap) {
3688+ unsigned int sid;
3689+
3690+ if (!squashfs_get_cached_block(s, &sid, start_block, offset,
3691+ sizeof(unsigned int), &start_block, &offset))
3692+ goto out;
3693+ SQUASHFS_SWAP_INTS((&sid), id, 1);
3694+ } else
3695+ if (!squashfs_get_cached_block(s, id, start_block, offset,
3696+ sizeof(unsigned int), &start_block, &offset))
3697+ goto out;
3698+
3699+ return 1;
3700+
3701+out:
3702+ return 0;
3703+}
3704+
3705+
3706+int read_id_index_table(struct super_block *s)
3707+{
3708+ struct squashfs_sb_info *msblk = s->s_fs_info;
3709+ struct squashfs_super_block *sblk = &msblk->sblk;
3710+ unsigned int length = SQUASHFS_ID_BLOCK_BYTES(sblk->no_ids);
3711+
3712+ TRACE("In read_id_index_table, length %d\n", length);
3713+
3714+ /* Allocate id index table */
3715+ msblk->id_table = kmalloc(length, GFP_KERNEL);
3716+ if (msblk->id_table == NULL) {
3717+ ERROR("Failed to allocate id index table\n");
3718+ return 0;
3719+ }
3720+
3721+ if (!squashfs_read_data(s, (char *) msblk->id_table,
3722+ sblk->id_table_start, length |
3723+ SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, length)) {
3724+ ERROR("unable to read id index table\n");
3725+ return 0;
3726+ }
3727+
3728+ if (msblk->swap) {
3729+ int i;
3730+ long long block;
3731+
3732+ for (i = 0; i < SQUASHFS_ID_BLOCKS(sblk->no_ids); i++) {
3733+ SQUASHFS_SWAP_ID_BLOCKS((&block), &msblk->id_table[i], 1);
3734+ msblk->id_table[i] = block;
3735+ }
3736+ }
3737+
3738+ return 1;
3739+}
3740diff -uNr a/fs/squashfs/inode.c b/fs/squashfs/inode.c
3741--- a/fs/squashfs/inode.c 1969-12-31 16:00:00.000000000 -0800
3742+++ b/fs/squashfs/inode.c 2008-08-13 16:14:50.000000000 -0700
3743@@ -0,0 +1,340 @@
3744+/*
3745+ * Squashfs - a compressed read only filesystem for Linux
3746+ *
3747+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
3748+ * Phillip Lougher <phillip@lougher.demon.co.uk>
3749+ *
3750+ * This program is free software; you can redistribute it and/or
3751+ * modify it under the terms of the GNU General Public License
3752+ * as published by the Free Software Foundation; either version 2,
3753+ * or (at your option) any later version.
3754+ *
3755+ * This program is distributed in the hope that it will be useful,
3756+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3757+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3758+ * GNU General Public License for more details.
3759+ *
3760+ * You should have received a copy of the GNU General Public License
3761+ * along with this program; if not, write to the Free Software
3762+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
3763+ *
3764+ * inode.c
3765+ */
3766+
3767+#include <linux/squashfs_fs.h>
3768+#include <linux/module.h>
3769+#include <linux/zlib.h>
3770+#include <linux/fs.h>
3771+#include <linux/squashfs_fs_sb.h>
3772+#include <linux/squashfs_fs_i.h>
3773+#include <linux/buffer_head.h>
3774+#include <linux/vfs.h>
3775+#include <linux/vmalloc.h>
3776+#include <linux/spinlock.h>
3777+#include <linux/smp_lock.h>
3778+#include <linux/exportfs.h>
3779+
3780+#include "squashfs.h"
3781+
3782+static int squashfs_new_inode(struct super_block *s, struct inode *i,
3783+ struct squashfs_base_inode_header *inodeb)
3784+{
3785+ if(get_id(s, inodeb->uid, &i->i_uid) == 0)
3786+ goto out;
3787+ if(get_id(s, inodeb->guid, &i->i_gid) == 0)
3788+ goto out;
3789+
3790+ i->i_ino = inodeb->inode_number;
3791+ i->i_mtime.tv_sec = inodeb->mtime;
3792+ i->i_atime.tv_sec = inodeb->mtime;
3793+ i->i_ctime.tv_sec = inodeb->mtime;
3794+ i->i_mode = inodeb->mode;
3795+ i->i_size = 0;
3796+
3797+ return 1;
3798+
3799+out:
3800+ return 0;
3801+}
3802+
3803+
3804+struct inode *squashfs_iget(struct super_block *s,
3805+ squashfs_inode_t inode, unsigned int inode_number)
3806+{
3807+ struct squashfs_sb_info *msblk = s->s_fs_info;
3808+ struct inode *i = iget_locked(s, inode_number);
3809+
3810+ TRACE("Entered squashfs_iget\n");
3811+
3812+ if(i && (i->i_state & I_NEW)) {
3813+ (msblk->read_inode)(i, inode);
3814+ unlock_new_inode(i);
3815+ }
3816+
3817+ return i;
3818+}
3819+
3820+
3821+int squashfs_read_inode(struct inode *i, squashfs_inode_t inode)
3822+{
3823+ struct super_block *s = i->i_sb;
3824+ struct squashfs_sb_info *msblk = s->s_fs_info;
3825+ struct squashfs_super_block *sblk = &msblk->sblk;
3826+ long long block = SQUASHFS_INODE_BLK(inode) + sblk->inode_table_start;
3827+ unsigned int offset = SQUASHFS_INODE_OFFSET(inode);
3828+ long long next_block;
3829+ unsigned int next_offset;
3830+ union squashfs_inode_header id, sid;
3831+ struct squashfs_base_inode_header *inodeb = &id.base, *sinodeb = &sid.base;
3832+
3833+ TRACE("Entered squashfs_read_inode\n");
3834+
3835+ if (msblk->swap) {
3836+ if (!squashfs_get_cached_block(s, sinodeb, block, offset,
3837+ sizeof(*sinodeb), &next_block, &next_offset))
3838+ goto failed_read;
3839+ SQUASHFS_SWAP_BASE_INODE_HEADER(inodeb, sinodeb, sizeof(*sinodeb));
3840+ } else
3841+ if (!squashfs_get_cached_block(s, inodeb, block, offset,
3842+ sizeof(*inodeb), &next_block, &next_offset))
3843+ goto failed_read;
3844+
3845+ if(squashfs_new_inode(s, i, inodeb) == 0)
3846+ goto failed_read;
3847+
3848+ switch(inodeb->inode_type) {
3849+ case SQUASHFS_FILE_TYPE: {
3850+ unsigned int frag_size;
3851+ long long frag_blk;
3852+ struct squashfs_reg_inode_header *inodep = &id.reg;
3853+ struct squashfs_reg_inode_header *sinodep = &sid.reg;
3854+
3855+ if (msblk->swap) {
3856+ if (!squashfs_get_cached_block(s, sinodep, block, offset,
3857+ sizeof(*sinodep), &next_block, &next_offset))
3858+ goto failed_read;
3859+ SQUASHFS_SWAP_REG_INODE_HEADER(inodep, sinodep);
3860+ } else
3861+ if (!squashfs_get_cached_block(s, inodep, block, offset,
3862+ sizeof(*inodep), &next_block, &next_offset))
3863+ goto failed_read;
3864+
3865+ frag_blk = SQUASHFS_INVALID_BLK;
3866+
3867+ if (inodep->fragment != SQUASHFS_INVALID_FRAG)
3868+ if(!get_fragment_location(s, inodep->fragment, &frag_blk,
3869+ &frag_size))
3870+ goto failed_read;
3871+
3872+ i->i_nlink = 1;
3873+ i->i_size = inodep->file_size;
3874+ i->i_fop = &generic_ro_fops;
3875+ i->i_mode |= S_IFREG;
3876+ i->i_blocks = ((i->i_size - 1) >> 9) + 1;
3877+ SQUASHFS_I(i)->u.s1.fragment_start_block = frag_blk;
3878+ SQUASHFS_I(i)->u.s1.fragment_size = frag_size;
3879+ SQUASHFS_I(i)->u.s1.fragment_offset = inodep->offset;
3880+ SQUASHFS_I(i)->start_block = inodep->start_block;
3881+ SQUASHFS_I(i)->u.s1.block_list_start = next_block;
3882+ SQUASHFS_I(i)->offset = next_offset;
3883+ i->i_data.a_ops = &squashfs_aops;
3884+
3885+ TRACE("File inode %x:%x, start_block %llx, "
3886+ "block_list_start %llx, offset %x\n",
3887+ SQUASHFS_INODE_BLK(inode), offset,
3888+ inodep->start_block, next_block,
3889+ next_offset);
3890+ break;
3891+ }
3892+ case SQUASHFS_LREG_TYPE: {
3893+ unsigned int frag_size;
3894+ long long frag_blk;
3895+ struct squashfs_lreg_inode_header *inodep = &id.lreg;
3896+ struct squashfs_lreg_inode_header *sinodep = &sid.lreg;
3897+
3898+ if (msblk->swap) {
3899+ if (!squashfs_get_cached_block(s, sinodep, block, offset,
3900+ sizeof(*sinodep), &next_block, &next_offset))
3901+ goto failed_read;
3902+ SQUASHFS_SWAP_LREG_INODE_HEADER(inodep, sinodep);
3903+ } else
3904+ if (!squashfs_get_cached_block(s, inodep, block, offset,
3905+ sizeof(*inodep), &next_block, &next_offset))
3906+ goto failed_read;
3907+
3908+ frag_blk = SQUASHFS_INVALID_BLK;
3909+
3910+ if (inodep->fragment != SQUASHFS_INVALID_FRAG)
3911+ if (!get_fragment_location(s, inodep->fragment, &frag_blk,
3912+ &frag_size))
3913+ goto failed_read;
3914+
3915+ i->i_nlink = inodep->nlink;
3916+ i->i_size = inodep->file_size;
3917+ i->i_fop = &generic_ro_fops;
3918+ i->i_mode |= S_IFREG;
3919+ i->i_blocks = ((inodep->file_size - inodep->sparse - 1) >> 9) + 1;
3920+
3921+ SQUASHFS_I(i)->u.s1.fragment_start_block = frag_blk;
3922+ SQUASHFS_I(i)->u.s1.fragment_size = frag_size;
3923+ SQUASHFS_I(i)->u.s1.fragment_offset = inodep->offset;
3924+ SQUASHFS_I(i)->start_block = inodep->start_block;
3925+ SQUASHFS_I(i)->u.s1.block_list_start = next_block;
3926+ SQUASHFS_I(i)->offset = next_offset;
3927+ i->i_data.a_ops = &squashfs_aops;
3928+
3929+ TRACE("File inode %x:%x, start_block %llx, "
3930+ "block_list_start %llx, offset %x\n",
3931+ SQUASHFS_INODE_BLK(inode), offset,
3932+ inodep->start_block, next_block,
3933+ next_offset);
3934+ break;
3935+ }
3936+ case SQUASHFS_DIR_TYPE: {
3937+ struct squashfs_dir_inode_header *inodep = &id.dir;
3938+ struct squashfs_dir_inode_header *sinodep = &sid.dir;
3939+
3940+ if (msblk->swap) {
3941+ if (!squashfs_get_cached_block(s, sinodep, block, offset,
3942+ sizeof(*sinodep), &next_block, &next_offset))
3943+ goto failed_read;
3944+ SQUASHFS_SWAP_DIR_INODE_HEADER(inodep, sinodep);
3945+ } else
3946+ if (!squashfs_get_cached_block(s, inodep, block, offset,
3947+ sizeof(*inodep), &next_block, &next_offset))
3948+ goto failed_read;
3949+
3950+ i->i_nlink = inodep->nlink;
3951+ i->i_size = inodep->file_size;
3952+ i->i_op = &squashfs_dir_inode_ops;
3953+ i->i_fop = &squashfs_dir_ops;
3954+ i->i_mode |= S_IFDIR;
3955+ SQUASHFS_I(i)->start_block = inodep->start_block;
3956+ SQUASHFS_I(i)->offset = inodep->offset;
3957+ SQUASHFS_I(i)->u.s2.directory_index_count = 0;
3958+ SQUASHFS_I(i)->u.s2.parent_inode = inodep->parent_inode;
3959+
3960+ TRACE("Directory inode %x:%x, start_block %x, offset "
3961+ "%x\n", SQUASHFS_INODE_BLK(inode),
3962+ offset, inodep->start_block,
3963+ inodep->offset);
3964+ break;
3965+ }
3966+ case SQUASHFS_LDIR_TYPE: {
3967+ struct squashfs_ldir_inode_header *inodep = &id.ldir;
3968+ struct squashfs_ldir_inode_header *sinodep = &sid.ldir;
3969+
3970+ if (msblk->swap) {
3971+ if (!squashfs_get_cached_block(s, sinodep, block, offset,
3972+ sizeof(*sinodep), &next_block, &next_offset))
3973+ goto failed_read;
3974+ SQUASHFS_SWAP_LDIR_INODE_HEADER(inodep, sinodep);
3975+ } else
3976+ if (!squashfs_get_cached_block(s, inodep, block, offset,
3977+ sizeof(*inodep), &next_block, &next_offset))
3978+ goto failed_read;
3979+
3980+ i->i_nlink = inodep->nlink;
3981+ i->i_size = inodep->file_size;
3982+ i->i_op = &squashfs_dir_inode_ops;
3983+ i->i_fop = &squashfs_dir_ops;
3984+ i->i_mode |= S_IFDIR;
3985+ SQUASHFS_I(i)->start_block = inodep->start_block;
3986+ SQUASHFS_I(i)->offset = inodep->offset;
3987+ SQUASHFS_I(i)->u.s2.directory_index_start = next_block;
3988+ SQUASHFS_I(i)->u.s2.directory_index_offset = next_offset;
3989+ SQUASHFS_I(i)->u.s2.directory_index_count = inodep->i_count;
3990+ SQUASHFS_I(i)->u.s2.parent_inode = inodep->parent_inode;
3991+
3992+ TRACE("Long directory inode %x:%x, start_block %x, offset %x\n",
3993+ SQUASHFS_INODE_BLK(inode), offset,
3994+ inodep->start_block, inodep->offset);
3995+ break;
3996+ }
3997+ case SQUASHFS_SYMLINK_TYPE: {
3998+ struct squashfs_symlink_inode_header *inodep = &id.symlink;
3999+ struct squashfs_symlink_inode_header *sinodep = &sid.symlink;
4000+
4001+ if (msblk->swap) {
4002+ if (!squashfs_get_cached_block(s, sinodep, block, offset,
4003+ sizeof(*sinodep), &next_block, &next_offset))
4004+ goto failed_read;
4005+ SQUASHFS_SWAP_SYMLINK_INODE_HEADER(inodep, sinodep);
4006+ } else
4007+ if (!squashfs_get_cached_block(s, inodep, block, offset,
4008+ sizeof(*inodep), &next_block, &next_offset))
4009+ goto failed_read;
4010+
4011+ i->i_nlink = inodep->nlink;
4012+ i->i_size = inodep->symlink_size;
4013+ i->i_op = &page_symlink_inode_operations;
4014+ i->i_data.a_ops = &squashfs_symlink_aops;
4015+ i->i_mode |= S_IFLNK;
4016+ SQUASHFS_I(i)->start_block = next_block;
4017+ SQUASHFS_I(i)->offset = next_offset;
4018+
4019+ TRACE("Symbolic link inode %x:%x, start_block %llx, offset %x\n",
4020+ SQUASHFS_INODE_BLK(inode), offset,
4021+ next_block, next_offset);
4022+ break;
4023+ }
4024+ case SQUASHFS_BLKDEV_TYPE:
4025+ case SQUASHFS_CHRDEV_TYPE: {
4026+ struct squashfs_dev_inode_header *inodep = &id.dev;
4027+ struct squashfs_dev_inode_header *sinodep = &sid.dev;
4028+
4029+ if (msblk->swap) {
4030+ if (!squashfs_get_cached_block(s, sinodep, block, offset,
4031+ sizeof(*sinodep), &next_block, &next_offset))
4032+ goto failed_read;
4033+ SQUASHFS_SWAP_DEV_INODE_HEADER(inodep, sinodep);
4034+ } else
4035+ if (!squashfs_get_cached_block(s, inodep, block, offset,
4036+ sizeof(*inodep), &next_block, &next_offset))
4037+ goto failed_read;
4038+
4039+ i->i_nlink = inodep->nlink;
4040+ i->i_mode |= (inodeb->inode_type == SQUASHFS_CHRDEV_TYPE) ?
4041+ S_IFCHR : S_IFBLK;
4042+ init_special_inode(i, i->i_mode, old_decode_dev(inodep->rdev));
4043+
4044+ TRACE("Device inode %x:%x, rdev %x\n",
4045+ SQUASHFS_INODE_BLK(inode), offset, inodep->rdev);
4046+ break;
4047+ }
4048+ case SQUASHFS_FIFO_TYPE:
4049+ case SQUASHFS_SOCKET_TYPE: {
4050+ struct squashfs_ipc_inode_header *inodep = &id.ipc;
4051+ struct squashfs_ipc_inode_header *sinodep = &sid.ipc;
4052+
4053+ if (msblk->swap) {
4054+ if (!squashfs_get_cached_block(s, sinodep, block, offset,
4055+ sizeof(*sinodep), &next_block, &next_offset))
4056+ goto failed_read;
4057+ SQUASHFS_SWAP_IPC_INODE_HEADER(inodep, sinodep);
4058+ } else
4059+ if (!squashfs_get_cached_block(s, inodep, block, offset,
4060+ sizeof(*inodep), &next_block, &next_offset))
4061+ goto failed_read;
4062+
4063+ i->i_nlink = inodep->nlink;
4064+ i->i_mode |= (inodeb->inode_type == SQUASHFS_FIFO_TYPE)
4065+ ? S_IFIFO : S_IFSOCK;
4066+ init_special_inode(i, i->i_mode, 0);
4067+ break;
4068+ }
4069+ default:
4070+ ERROR("Unknown inode type %d in squashfs_iget!\n",
4071+ inodeb->inode_type);
4072+ goto failed_read1;
4073+ }
4074+
4075+ return 1;
4076+
4077+failed_read:
4078+ ERROR("Unable to read inode [%llx:%x]\n", block, offset);
4079+
4080+failed_read1:
4081+ make_bad_inode(i);
4082+ return 0;
4083+}
4084diff -uNr a/fs/squashfs/Makefile b/fs/squashfs/Makefile
4085--- a/fs/squashfs/Makefile 1969-12-31 16:00:00.000000000 -0800
4086+++ b/fs/squashfs/Makefile 2008-08-13 16:14:50.000000000 -0700
4087@@ -0,0 +1,8 @@
4088+#
4089+# Makefile for the linux squashfs routines.
4090+#
4091+
4092+obj-$(CONFIG_SQUASHFS) += squashfs.o
4093+squashfs-y += block.o cache.o dir.o export.o file.o fragment.o id.o inode.o
4094+squashfs-y += namei.o super.o symlink.o
4095+#squashfs-y += squashfs2_0.o
4096diff -uNr a/fs/squashfs/namei.c b/fs/squashfs/namei.c
4097--- a/fs/squashfs/namei.c 1969-12-31 16:00:00.000000000 -0800
4098+++ b/fs/squashfs/namei.c 2008-08-13 16:14:50.000000000 -0700
4099@@ -0,0 +1,200 @@
4100+/*
4101+ * Squashfs - a compressed read only filesystem for Linux
4102+ *
4103+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
4104+ * Phillip Lougher <phillip@lougher.demon.co.uk>
4105+ *
4106+ * This program is free software; you can redistribute it and/or
4107+ * modify it under the terms of the GNU General Public License
4108+ * as published by the Free Software Foundation; either version 2,
4109+ * or (at your option) any later version.
4110+ *
4111+ * This program is distributed in the hope that it will be useful,
4112+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4113+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4114+ * GNU General Public License for more details.
4115+ *
4116+ * You should have received a copy of the GNU General Public License
4117+ * along with this program; if not, write to the Free Software
4118+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
4119+ *
4120+ * namei.c
4121+ */
4122+
4123+#include <linux/squashfs_fs.h>
4124+#include <linux/module.h>
4125+#include <linux/zlib.h>
4126+#include <linux/fs.h>
4127+#include <linux/squashfs_fs_sb.h>
4128+#include <linux/squashfs_fs_i.h>
4129+#include <linux/buffer_head.h>
4130+#include <linux/vfs.h>
4131+#include <linux/vmalloc.h>
4132+#include <linux/spinlock.h>
4133+#include <linux/smp_lock.h>
4134+#include <linux/exportfs.h>
4135+
4136+#include "squashfs.h"
4137+
4138+static int get_dir_index_using_name(struct super_block *s,
4139+ long long *next_block, unsigned int *next_offset,
4140+ long long index_start, unsigned int index_offset, int i_count,
4141+ const char *name, int size)
4142+{
4143+ struct squashfs_sb_info *msblk = s->s_fs_info;
4144+ struct squashfs_super_block *sblk = &msblk->sblk;
4145+ int i, length = 0;
4146+ struct squashfs_dir_index *index;
4147+ char *str;
4148+
4149+ TRACE("Entered get_dir_index_using_name, i_count %d\n", i_count);
4150+
4151+ str = kmalloc(sizeof(struct squashfs_dir_index) +
4152+ (SQUASHFS_NAME_LEN + 1) * 2, GFP_KERNEL);
4153+ if (str == NULL) {
4154+ ERROR("Failed to allocate squashfs_dir_index\n");
4155+ goto failure;
4156+ }
4157+
4158+ index = (struct squashfs_dir_index *) (str + SQUASHFS_NAME_LEN + 1);
4159+ strncpy(str, name, size);
4160+ str[size] = '\0';
4161+
4162+ for (i = 0; i < i_count; i++) {
4163+ if (msblk->swap) {
4164+ struct squashfs_dir_index sindex;
4165+ squashfs_get_cached_block(s, &sindex, index_start, index_offset,
4166+ sizeof(sindex), &index_start, &index_offset);
4167+ SQUASHFS_SWAP_DIR_INDEX(index, &sindex);
4168+ } else
4169+ squashfs_get_cached_block(s, index, index_start, index_offset,
4170+ sizeof(struct squashfs_dir_index), &index_start, &index_offset);
4171+
4172+ squashfs_get_cached_block(s, index->name, index_start, index_offset,
4173+ index->size + 1, &index_start, &index_offset);
4174+
4175+ index->name[index->size + 1] = '\0';
4176+
4177+ if (strcmp(index->name, str) > 0)
4178+ break;
4179+
4180+ length = index->index;
4181+ *next_block = index->start_block + sblk->directory_table_start;
4182+ }
4183+
4184+ *next_offset = (length + *next_offset) % SQUASHFS_METADATA_SIZE;
4185+ kfree(str);
4186+
4187+failure:
4188+ return length + 3;
4189+}
4190+
4191+
4192+static struct dentry *squashfs_lookup(struct inode *i, struct dentry *dentry,
4193+ struct nameidata *nd)
4194+{
4195+ const unsigned char *name = dentry->d_name.name;
4196+ int len = dentry->d_name.len;
4197+ struct inode *inode = NULL;
4198+ struct squashfs_sb_info *msblk = i->i_sb->s_fs_info;
4199+ struct squashfs_super_block *sblk = &msblk->sblk;
4200+ long long next_block = SQUASHFS_I(i)->start_block +
4201+ sblk->directory_table_start;
4202+ int next_offset = SQUASHFS_I(i)->offset, length = 0, dir_count;
4203+ struct squashfs_dir_header dirh;
4204+ struct squashfs_dir_entry *dire;
4205+
4206+ TRACE("Entered squashfs_lookup [%llx:%x]\n", next_block, next_offset);
4207+
4208+ dire = kmalloc(sizeof(struct squashfs_dir_entry) +
4209+ SQUASHFS_NAME_LEN + 1, GFP_KERNEL);
4210+ if (dire == NULL) {
4211+ ERROR("Failed to allocate squashfs_dir_entry\n");
4212+ goto exit_lookup;
4213+ }
4214+
4215+ if (len > SQUASHFS_NAME_LEN)
4216+ goto exit_lookup;
4217+
4218+ length = get_dir_index_using_name(i->i_sb, &next_block, &next_offset,
4219+ SQUASHFS_I(i)->u.s2.directory_index_start,
4220+ SQUASHFS_I(i)->u.s2.directory_index_offset,
4221+ SQUASHFS_I(i)->u.s2.directory_index_count, name, len);
4222+
4223+ while (length < i_size_read(i)) {
4224+ /* read directory header */
4225+ if (msblk->swap) {
4226+ struct squashfs_dir_header sdirh;
4227+ if (!squashfs_get_cached_block(i->i_sb, &sdirh, next_block,
4228+ next_offset, sizeof(sdirh), &next_block, &next_offset))
4229+ goto failed_read;
4230+
4231+ length += sizeof(sdirh);
4232+ SQUASHFS_SWAP_DIR_HEADER(&dirh, &sdirh);
4233+ } else {
4234+ if (!squashfs_get_cached_block(i->i_sb, &dirh, next_block,
4235+ next_offset, sizeof(dirh), &next_block, &next_offset))
4236+ goto failed_read;
4237+
4238+ length += sizeof(dirh);
4239+ }
4240+
4241+ dir_count = dirh.count + 1;
4242+ while (dir_count--) {
4243+ if (msblk->swap) {
4244+ struct squashfs_dir_entry sdire;
4245+ if (!squashfs_get_cached_block(i->i_sb, &sdire, next_block,
4246+ next_offset, sizeof(sdire), &next_block, &next_offset))
4247+ goto failed_read;
4248+
4249+ length += sizeof(sdire);
4250+ SQUASHFS_SWAP_DIR_ENTRY(dire, &sdire);
4251+ } else {
4252+ if (!squashfs_get_cached_block(i->i_sb, dire, next_block,
4253+ next_offset, sizeof(*dire), &next_block, &next_offset))
4254+ goto failed_read;
4255+
4256+ length += sizeof(*dire);
4257+ }
4258+
4259+ if (!squashfs_get_cached_block(i->i_sb, dire->name, next_block,
4260+ next_offset, dire->size + 1, &next_block, &next_offset))
4261+ goto failed_read;
4262+
4263+ length += dire->size + 1;
4264+
4265+ if (name[0] < dire->name[0])
4266+ goto exit_lookup;
4267+
4268+ if ((len == dire->size + 1) && !strncmp(name, dire->name, len)) {
4269+ squashfs_inode_t ino = SQUASHFS_MKINODE(dirh.start_block,
4270+ dire->offset);
4271+
4272+ TRACE("calling squashfs_iget for directory entry %s, inode"
4273+ " %x:%x, %d\n", name, dirh.start_block, dire->offset,
4274+ dirh.inode_number + dire->inode_number);
4275+
4276+ inode = squashfs_iget(i->i_sb, ino, dirh.inode_number + dire->inode_number);
4277+
4278+ goto exit_lookup;
4279+ }
4280+ }
4281+ }
4282+
4283+exit_lookup:
4284+ kfree(dire);
4285+ if (inode)
4286+ return d_splice_alias(inode, dentry);
4287+ d_add(dentry, inode);
4288+ return ERR_PTR(0);
4289+
4290+failed_read:
4291+ ERROR("Unable to read directory block [%llx:%x]\n", next_block,
4292+ next_offset);
4293+ goto exit_lookup;
4294+}
4295+
4296+
4297+const struct inode_operations squashfs_dir_inode_ops = {
4298+ .lookup = squashfs_lookup
4299+};
4300diff -uNr a/fs/squashfs/squashfs2_0.c b/fs/squashfs/squashfs2_0.c
4301--- a/fs/squashfs/squashfs2_0.c 1969-12-31 16:00:00.000000000 -0800
4302+++ b/fs/squashfs/squashfs2_0.c 2008-08-13 16:14:50.000000000 -0700
4303@@ -0,0 +1,740 @@
4304+/*
4305+ * Squashfs - a compressed read only filesystem for Linux
4306+ *
4307+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
4308+ * Phillip Lougher <phillip@lougher.demon.co.uk>
4309+ *
4310+ * This program is free software; you can redistribute it and/or
4311+ * modify it under the terms of the GNU General Public License
4312+ * as published by the Free Software Foundation; either version 2,
4313+ * or (at your option) any later version.
4314+ *
4315+ * This program is distributed in the hope that it will be useful,
4316+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4317+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4318+ * GNU General Public License for more details.
4319+ *
4320+ * You should have received a copy of the GNU General Public License
4321+ * along with this program; if not, write to the Free Software
4322+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
4323+ *
4324+ * squashfs2_0.c
4325+ */
4326+
4327+#include <linux/squashfs_fs.h>
4328+#include <linux/module.h>
4329+#include <linux/zlib.h>
4330+#include <linux/fs.h>
4331+#include <linux/squashfs_fs_sb.h>
4332+#include <linux/squashfs_fs_i.h>
4333+
4334+#include "squashfs.h"
4335+static int squashfs_readdir_2(struct file *file, void *dirent, filldir_t filldir);
4336+static struct dentry *squashfs_lookup_2(struct inode *, struct dentry *,
4337+ struct nameidata *);
4338+
4339+static struct file_operations squashfs_dir_ops_2 = {
4340+ .read = generic_read_dir,
4341+ .readdir = squashfs_readdir_2
4342+};
4343+
4344+static struct inode_operations squashfs_dir_inode_ops_2 = {
4345+ .lookup = squashfs_lookup_2
4346+};
4347+
4348+static unsigned char squashfs_filetype_table[] = {
4349+ DT_UNKNOWN, DT_DIR, DT_REG, DT_LNK, DT_BLK, DT_CHR, DT_FIFO, DT_SOCK
4350+};
4351+
4352+static int read_fragment_index_table_2(struct super_block *s)
4353+{
4354+ struct squashfs_sb_info *msblk = s->s_fs_info;
4355+ struct squashfs_super_block *sblk = &msblk->sblk;
4356+
4357+ if (!(msblk->fragment_index_2 = kmalloc(SQUASHFS_FRAGMENT_INDEX_BYTES_2
4358+ (sblk->fragments), GFP_KERNEL))) {
4359+ ERROR("Failed to allocate uid/gid table\n");
4360+ return 0;
4361+ }
4362+
4363+ if (SQUASHFS_FRAGMENT_INDEX_BYTES_2(sblk->fragments) &&
4364+ !squashfs_read_data(s, (char *)
4365+ msblk->fragment_index_2,
4366+ sblk->fragment_table_start,
4367+ SQUASHFS_FRAGMENT_INDEX_BYTES_2
4368+ (sblk->fragments) |
4369+ SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, SQUASHFS_FRAGMENT_INDEX_BYTES_2(sblk->fragments))) {
4370+ ERROR("unable to read fragment index table\n");
4371+ return 0;
4372+ }
4373+
4374+ if (msblk->swap) {
4375+ int i;
4376+ unsigned int fragment;
4377+
4378+ for (i = 0; i < SQUASHFS_FRAGMENT_INDEXES_2(sblk->fragments);
4379+ i++) {
4380+ SQUASHFS_SWAP_FRAGMENT_INDEXES_2((&fragment),
4381+ &msblk->fragment_index_2[i], 1);
4382+ msblk->fragment_index_2[i] = fragment;
4383+ }
4384+ }
4385+
4386+ return 1;
4387+}
4388+
4389+
4390+static int get_fragment_location_2(struct super_block *s, unsigned int fragment,
4391+ long long *fragment_start_block,
4392+ unsigned int *fragment_size)
4393+{
4394+ struct squashfs_sb_info *msblk = s->s_fs_info;
4395+ long long start_block =
4396+ msblk->fragment_index_2[SQUASHFS_FRAGMENT_INDEX_2(fragment)];
4397+ int offset = SQUASHFS_FRAGMENT_INDEX_OFFSET_2(fragment);
4398+ struct squashfs_fragment_entry_2 fragment_entry;
4399+
4400+ if (msblk->swap) {
4401+ struct squashfs_fragment_entry_2 sfragment_entry;
4402+
4403+ if (!squashfs_get_cached_block(s, (char *) &sfragment_entry,
4404+ start_block, offset,
4405+ sizeof(sfragment_entry), &start_block,
4406+ &offset))
4407+ goto out;
4408+ SQUASHFS_SWAP_FRAGMENT_ENTRY_2(&fragment_entry, &sfragment_entry);
4409+ } else
4410+ if (!squashfs_get_cached_block(s, (char *) &fragment_entry,
4411+ start_block, offset,
4412+ sizeof(fragment_entry), &start_block,
4413+ &offset))
4414+ goto out;
4415+
4416+ *fragment_start_block = fragment_entry.start_block;
4417+ *fragment_size = fragment_entry.size;
4418+
4419+ return 1;
4420+
4421+out:
4422+ return 0;
4423+}
4424+
4425+
4426+static void squashfs_new_inode(struct squashfs_sb_info *msblk, struct inode *i,
4427+ struct squashfs_base_inode_header_2 *inodeb, unsigned int ino)
4428+{
4429+ struct squashfs_super_block *sblk = &msblk->sblk;
4430+
4431+ i->i_ino = ino;
4432+ i->i_mtime.tv_sec = sblk->mkfs_time;
4433+ i->i_atime.tv_sec = sblk->mkfs_time;
4434+ i->i_ctime.tv_sec = sblk->mkfs_time;
4435+ i->i_uid = msblk->uid[inodeb->uid];
4436+ i->i_mode = inodeb->mode;
4437+ i->i_nlink = 1;
4438+ i->i_size = 0;
4439+ if (inodeb->guid == SQUASHFS_GUIDS)
4440+ i->i_gid = i->i_uid;
4441+ else
4442+ i->i_gid = msblk->guid[inodeb->guid];
4443+}
4444+
4445+
4446+static int squashfs_read_inode_2(struct inode *i, squashfs_inode_t inode)
4447+{
4448+ struct super_block *s = i->i_sb;
4449+ struct squashfs_sb_info *msblk = s->s_fs_info;
4450+ struct squashfs_super_block *sblk = &msblk->sblk;
4451+ unsigned int block = SQUASHFS_INODE_BLK(inode) +
4452+ sblk->inode_table_start;
4453+ unsigned int offset = SQUASHFS_INODE_OFFSET(inode);
4454+ unsigned int ino = SQUASHFS_MK_VFS_INODE(block -
4455+ sblk->inode_table_start, offset);
4456+ long long next_block;
4457+ unsigned int next_offset;
4458+ union squashfs_inode_header_2 id, sid;
4459+ struct squashfs_base_inode_header_2 *inodeb = &id.base,
4460+ *sinodeb = &sid.base;
4461+
4462+ TRACE("Entered squashfs_read_inode_2\n");
4463+
4464+ if (msblk->swap) {
4465+ if (!squashfs_get_cached_block(s, (char *) sinodeb, block,
4466+ offset, sizeof(*sinodeb), &next_block,
4467+ &next_offset))
4468+ goto failed_read;
4469+ SQUASHFS_SWAP_BASE_INODE_HEADER_2(inodeb, sinodeb,
4470+ sizeof(*sinodeb));
4471+ } else
4472+ if (!squashfs_get_cached_block(s, (char *) inodeb, block,
4473+ offset, sizeof(*inodeb), &next_block,
4474+ &next_offset))
4475+ goto failed_read;
4476+
4477+ squashfs_new_inode(msblk, i, inodeb, ino);
4478+
4479+ switch(inodeb->inode_type) {
4480+ case SQUASHFS_FILE_TYPE: {
4481+ struct squashfs_reg_inode_header_2 *inodep = &id.reg;
4482+ struct squashfs_reg_inode_header_2 *sinodep = &sid.reg;
4483+ long long frag_blk;
4484+ unsigned int frag_size = 0;
4485+
4486+ if (msblk->swap) {
4487+ if (!squashfs_get_cached_block(s, (char *)
4488+ sinodep, block, offset,
4489+ sizeof(*sinodep), &next_block,
4490+ &next_offset))
4491+ goto failed_read;
4492+ SQUASHFS_SWAP_REG_INODE_HEADER_2(inodep, sinodep);
4493+ } else
4494+ if (!squashfs_get_cached_block(s, (char *)
4495+ inodep, block, offset,
4496+ sizeof(*inodep), &next_block,
4497+ &next_offset))
4498+ goto failed_read;
4499+
4500+ frag_blk = SQUASHFS_INVALID_BLK;
4501+ if (inodep->fragment != SQUASHFS_INVALID_FRAG &&
4502+ !get_fragment_location_2(s,
4503+ inodep->fragment, &frag_blk, &frag_size))
4504+ goto failed_read;
4505+
4506+ i->i_size = inodep->file_size;
4507+ i->i_fop = &generic_ro_fops;
4508+ i->i_mode |= S_IFREG;
4509+ i->i_mtime.tv_sec = inodep->mtime;
4510+ i->i_atime.tv_sec = inodep->mtime;
4511+ i->i_ctime.tv_sec = inodep->mtime;
4512+ i->i_blocks = ((i->i_size - 1) >> 9) + 1;
4513+ SQUASHFS_I(i)->u.s1.fragment_start_block = frag_blk;
4514+ SQUASHFS_I(i)->u.s1.fragment_size = frag_size;
4515+ SQUASHFS_I(i)->u.s1.fragment_offset = inodep->offset;
4516+ SQUASHFS_I(i)->start_block = inodep->start_block;
4517+ SQUASHFS_I(i)->u.s1.block_list_start = next_block;
4518+ SQUASHFS_I(i)->offset = next_offset;
4519+ i->i_data.a_ops = &squashfs_aops;
4520+
4521+ TRACE("File inode %x:%x, start_block %x, "
4522+ "block_list_start %llx, offset %x\n",
4523+ SQUASHFS_INODE_BLK(inode), offset,
4524+ inodep->start_block, next_block,
4525+ next_offset);
4526+ break;
4527+ }
4528+ case SQUASHFS_DIR_TYPE: {
4529+ struct squashfs_dir_inode_header_2 *inodep = &id.dir;
4530+ struct squashfs_dir_inode_header_2 *sinodep = &sid.dir;
4531+
4532+ if (msblk->swap) {
4533+ if (!squashfs_get_cached_block(s, (char *)
4534+ sinodep, block, offset,
4535+ sizeof(*sinodep), &next_block,
4536+ &next_offset))
4537+ goto failed_read;
4538+ SQUASHFS_SWAP_DIR_INODE_HEADER_2(inodep, sinodep);
4539+ } else
4540+ if (!squashfs_get_cached_block(s, (char *)
4541+ inodep, block, offset,
4542+ sizeof(*inodep), &next_block,
4543+ &next_offset))
4544+ goto failed_read;
4545+
4546+ i->i_size = inodep->file_size;
4547+ i->i_op = &squashfs_dir_inode_ops_2;
4548+ i->i_fop = &squashfs_dir_ops_2;
4549+ i->i_mode |= S_IFDIR;
4550+ i->i_mtime.tv_sec = inodep->mtime;
4551+ i->i_atime.tv_sec = inodep->mtime;
4552+ i->i_ctime.tv_sec = inodep->mtime;
4553+ SQUASHFS_I(i)->start_block = inodep->start_block;
4554+ SQUASHFS_I(i)->offset = inodep->offset;
4555+ SQUASHFS_I(i)->u.s2.directory_index_count = 0;
4556+ SQUASHFS_I(i)->u.s2.parent_inode = 0;
4557+
4558+ TRACE("Directory inode %x:%x, start_block %x, offset "
4559+ "%x\n", SQUASHFS_INODE_BLK(inode),
4560+ offset, inodep->start_block,
4561+ inodep->offset);
4562+ break;
4563+ }
4564+ case SQUASHFS_LDIR_TYPE: {
4565+ struct squashfs_ldir_inode_header_2 *inodep = &id.ldir;
4566+ struct squashfs_ldir_inode_header_2 *sinodep = &sid.ldir;
4567+
4568+ if (msblk->swap) {
4569+ if (!squashfs_get_cached_block(s, (char *)
4570+ sinodep, block, offset,
4571+ sizeof(*sinodep), &next_block,
4572+ &next_offset))
4573+ goto failed_read;
4574+ SQUASHFS_SWAP_LDIR_INODE_HEADER_2(inodep,
4575+ sinodep);
4576+ } else
4577+ if (!squashfs_get_cached_block(s, (char *)
4578+ inodep, block, offset,
4579+ sizeof(*inodep), &next_block,
4580+ &next_offset))
4581+ goto failed_read;
4582+
4583+ i->i_size = inodep->file_size;
4584+ i->i_op = &squashfs_dir_inode_ops_2;
4585+ i->i_fop = &squashfs_dir_ops_2;
4586+ i->i_mode |= S_IFDIR;
4587+ i->i_mtime.tv_sec = inodep->mtime;
4588+ i->i_atime.tv_sec = inodep->mtime;
4589+ i->i_ctime.tv_sec = inodep->mtime;
4590+ SQUASHFS_I(i)->start_block = inodep->start_block;
4591+ SQUASHFS_I(i)->offset = inodep->offset;
4592+ SQUASHFS_I(i)->u.s2.directory_index_start = next_block;
4593+ SQUASHFS_I(i)->u.s2.directory_index_offset =
4594+ next_offset;
4595+ SQUASHFS_I(i)->u.s2.directory_index_count =
4596+ inodep->i_count;
4597+ SQUASHFS_I(i)->u.s2.parent_inode = 0;
4598+
4599+ TRACE("Long directory inode %x:%x, start_block %x, "
4600+ "offset %x\n",
4601+ SQUASHFS_INODE_BLK(inode), offset,
4602+ inodep->start_block, inodep->offset);
4603+ break;
4604+ }
4605+ case SQUASHFS_SYMLINK_TYPE: {
4606+ struct squashfs_symlink_inode_header_2 *inodep =
4607+ &id.symlink;
4608+ struct squashfs_symlink_inode_header_2 *sinodep =
4609+ &sid.symlink;
4610+
4611+ if (msblk->swap) {
4612+ if (!squashfs_get_cached_block(s, (char *)
4613+ sinodep, block, offset,
4614+ sizeof(*sinodep), &next_block,
4615+ &next_offset))
4616+ goto failed_read;
4617+ SQUASHFS_SWAP_SYMLINK_INODE_HEADER_2(inodep,
4618+ sinodep);
4619+ } else
4620+ if (!squashfs_get_cached_block(s, (char *)
4621+ inodep, block, offset,
4622+ sizeof(*inodep), &next_block,
4623+ &next_offset))
4624+ goto failed_read;
4625+
4626+ i->i_size = inodep->symlink_size;
4627+ i->i_op = &page_symlink_inode_operations;
4628+ i->i_data.a_ops = &squashfs_symlink_aops;
4629+ i->i_mode |= S_IFLNK;
4630+ SQUASHFS_I(i)->start_block = next_block;
4631+ SQUASHFS_I(i)->offset = next_offset;
4632+
4633+ TRACE("Symbolic link inode %x:%x, start_block %llx, "
4634+ "offset %x\n",
4635+ SQUASHFS_INODE_BLK(inode), offset,
4636+ next_block, next_offset);
4637+ break;
4638+ }
4639+ case SQUASHFS_BLKDEV_TYPE:
4640+ case SQUASHFS_CHRDEV_TYPE: {
4641+ struct squashfs_dev_inode_header_2 *inodep = &id.dev;
4642+ struct squashfs_dev_inode_header_2 *sinodep = &sid.dev;
4643+
4644+ if (msblk->swap) {
4645+ if (!squashfs_get_cached_block(s, (char *)
4646+ sinodep, block, offset,
4647+ sizeof(*sinodep), &next_block,
4648+ &next_offset))
4649+ goto failed_read;
4650+ SQUASHFS_SWAP_DEV_INODE_HEADER_2(inodep, sinodep);
4651+ } else
4652+ if (!squashfs_get_cached_block(s, (char *)
4653+ inodep, block, offset,
4654+ sizeof(*inodep), &next_block,
4655+ &next_offset))
4656+ goto failed_read;
4657+
4658+ i->i_mode |= (inodeb->inode_type ==
4659+ SQUASHFS_CHRDEV_TYPE) ? S_IFCHR :
4660+ S_IFBLK;
4661+ init_special_inode(i, i->i_mode,
4662+ old_decode_dev(inodep->rdev));
4663+
4664+ TRACE("Device inode %x:%x, rdev %x\n",
4665+ SQUASHFS_INODE_BLK(inode), offset,
4666+ inodep->rdev);
4667+ break;
4668+ }
4669+ case SQUASHFS_FIFO_TYPE:
4670+ case SQUASHFS_SOCKET_TYPE: {
4671+
4672+ i->i_mode |= (inodeb->inode_type == SQUASHFS_FIFO_TYPE)
4673+ ? S_IFIFO : S_IFSOCK;
4674+ init_special_inode(i, i->i_mode, 0);
4675+ break;
4676+ }
4677+ default:
4678+ ERROR("Unknown inode type %d in squashfs_iget!\n",
4679+ inodeb->inode_type);
4680+ goto failed_read1;
4681+ }
4682+
4683+ return 1;
4684+
4685+failed_read:
4686+ ERROR("Unable to read inode [%x:%x]\n", block, offset);
4687+
4688+failed_read1:
4689+ return 0;
4690+}
4691+
4692+
4693+static int get_dir_index_using_offset(struct super_block *s, long long
4694+ *next_block, unsigned int *next_offset,
4695+ long long index_start,
4696+ unsigned int index_offset, int i_count,
4697+ long long f_pos)
4698+{
4699+ struct squashfs_sb_info *msblk = s->s_fs_info;
4700+ struct squashfs_super_block *sblk = &msblk->sblk;
4701+ int i, length = 0;
4702+ struct squashfs_dir_index_2 index;
4703+
4704+ TRACE("Entered get_dir_index_using_offset, i_count %d, f_pos %d\n",
4705+ i_count, (unsigned int) f_pos);
4706+
4707+ if (f_pos == 0)
4708+ goto finish;
4709+
4710+ for (i = 0; i < i_count; i++) {
4711+ if (msblk->swap) {
4712+ struct squashfs_dir_index_2 sindex;
4713+ squashfs_get_cached_block(s, (char *) &sindex,
4714+ index_start, index_offset,
4715+ sizeof(sindex), &index_start,
4716+ &index_offset);
4717+ SQUASHFS_SWAP_DIR_INDEX_2(&index, &sindex);
4718+ } else
4719+ squashfs_get_cached_block(s, (char *) &index,
4720+ index_start, index_offset,
4721+ sizeof(index), &index_start,
4722+ &index_offset);
4723+
4724+ if (index.index > f_pos)
4725+ break;
4726+
4727+ squashfs_get_cached_block(s, NULL, index_start, index_offset,
4728+ index.size + 1, &index_start,
4729+ &index_offset);
4730+
4731+ length = index.index;
4732+ *next_block = index.start_block + sblk->directory_table_start;
4733+ }
4734+
4735+ *next_offset = (length + *next_offset) % SQUASHFS_METADATA_SIZE;
4736+
4737+finish:
4738+ return length;
4739+}
4740+
4741+
4742+static int get_dir_index_using_name(struct super_block *s, long long
4743+ *next_block, unsigned int *next_offset,
4744+ long long index_start,
4745+ unsigned int index_offset, int i_count,
4746+ const char *name, int size)
4747+{
4748+ struct squashfs_sb_info *msblk = s->s_fs_info;
4749+ struct squashfs_super_block *sblk = &msblk->sblk;
4750+ int i, length = 0;
4751+ struct squashfs_dir_index_2 *index;
4752+ char *str;
4753+
4754+ TRACE("Entered get_dir_index_using_name, i_count %d\n", i_count);
4755+
4756+ if (!(str = kmalloc(sizeof(struct squashfs_dir_index) +
4757+ (SQUASHFS_NAME_LEN + 1) * 2, GFP_KERNEL))) {
4758+ ERROR("Failed to allocate squashfs_dir_index\n");
4759+ goto failure;
4760+ }
4761+
4762+ index = (struct squashfs_dir_index_2 *) (str + SQUASHFS_NAME_LEN + 1);
4763+ strncpy(str, name, size);
4764+ str[size] = '\0';
4765+
4766+ for (i = 0; i < i_count; i++) {
4767+ if (msblk->swap) {
4768+ struct squashfs_dir_index_2 sindex;
4769+ squashfs_get_cached_block(s, (char *) &sindex,
4770+ index_start, index_offset,
4771+ sizeof(sindex), &index_start,
4772+ &index_offset);
4773+ SQUASHFS_SWAP_DIR_INDEX_2(index, &sindex);
4774+ } else
4775+ squashfs_get_cached_block(s, (char *) index,
4776+ index_start, index_offset,
4777+ sizeof(struct squashfs_dir_index_2),
4778+ &index_start, &index_offset);
4779+
4780+ squashfs_get_cached_block(s, index->name, index_start,
4781+ index_offset, index->size + 1,
4782+ &index_start, &index_offset);
4783+
4784+ index->name[index->size + 1] = '\0';
4785+
4786+ if (strcmp(index->name, str) > 0)
4787+ break;
4788+
4789+ length = index->index;
4790+ *next_block = index->start_block + sblk->directory_table_start;
4791+ }
4792+
4793+ *next_offset = (length + *next_offset) % SQUASHFS_METADATA_SIZE;
4794+ kfree(str);
4795+failure:
4796+ return length;
4797+}
4798+
4799+
4800+static int squashfs_readdir_2(struct file *file, void *dirent, filldir_t filldir)
4801+{
4802+ struct inode *i = file->f_dentry->d_inode;
4803+ struct squashfs_sb_info *msblk = i->i_sb->s_fs_info;
4804+ struct squashfs_super_block *sblk = &msblk->sblk;
4805+ long long next_block = SQUASHFS_I(i)->start_block +
4806+ sblk->directory_table_start;
4807+ int next_offset = SQUASHFS_I(i)->offset, length = 0,
4808+ dir_count;
4809+ struct squashfs_dir_header_2 dirh;
4810+ struct squashfs_dir_entry_2 *dire;
4811+
4812+ TRACE("Entered squashfs_readdir_2 [%llx:%x]\n", next_block, next_offset);
4813+
4814+ if (!(dire = kmalloc(sizeof(struct squashfs_dir_entry) +
4815+ SQUASHFS_NAME_LEN + 1, GFP_KERNEL))) {
4816+ ERROR("Failed to allocate squashfs_dir_entry\n");
4817+ goto finish;
4818+ }
4819+
4820+ length = get_dir_index_using_offset(i->i_sb, &next_block, &next_offset,
4821+ SQUASHFS_I(i)->u.s2.directory_index_start,
4822+ SQUASHFS_I(i)->u.s2.directory_index_offset,
4823+ SQUASHFS_I(i)->u.s2.directory_index_count,
4824+ file->f_pos);
4825+
4826+ while (length < i_size_read(i)) {
4827+ /* read directory header */
4828+ if (msblk->swap) {
4829+ struct squashfs_dir_header_2 sdirh;
4830+
4831+ if (!squashfs_get_cached_block(i->i_sb, (char *) &sdirh,
4832+ next_block, next_offset, sizeof(sdirh),
4833+ &next_block, &next_offset))
4834+ goto failed_read;
4835+
4836+ length += sizeof(sdirh);
4837+ SQUASHFS_SWAP_DIR_HEADER_2(&dirh, &sdirh);
4838+ } else {
4839+ if (!squashfs_get_cached_block(i->i_sb, (char *) &dirh,
4840+ next_block, next_offset, sizeof(dirh),
4841+ &next_block, &next_offset))
4842+ goto failed_read;
4843+
4844+ length += sizeof(dirh);
4845+ }
4846+
4847+ dir_count = dirh.count + 1;
4848+ while (dir_count--) {
4849+ if (msblk->swap) {
4850+ struct squashfs_dir_entry_2 sdire;
4851+ if (!squashfs_get_cached_block(i->i_sb, (char *)
4852+ &sdire, next_block, next_offset,
4853+ sizeof(sdire), &next_block,
4854+ &next_offset))
4855+ goto failed_read;
4856+
4857+ length += sizeof(sdire);
4858+ SQUASHFS_SWAP_DIR_ENTRY_2(dire, &sdire);
4859+ } else {
4860+ if (!squashfs_get_cached_block(i->i_sb, (char *)
4861+ dire, next_block, next_offset,
4862+ sizeof(*dire), &next_block,
4863+ &next_offset))
4864+ goto failed_read;
4865+
4866+ length += sizeof(*dire);
4867+ }
4868+
4869+ if (!squashfs_get_cached_block(i->i_sb, dire->name,
4870+ next_block, next_offset,
4871+ dire->size + 1, &next_block,
4872+ &next_offset))
4873+ goto failed_read;
4874+
4875+ length += dire->size + 1;
4876+
4877+ if (file->f_pos >= length)
4878+ continue;
4879+
4880+ dire->name[dire->size + 1] = '\0';
4881+
4882+ TRACE("Calling filldir(%x, %s, %d, %d, %x:%x, %d)\n",
4883+ (unsigned int) dirent, dire->name,
4884+ dire->size + 1, (int) file->f_pos,
4885+ dirh.start_block, dire->offset,
4886+ squashfs_filetype_table[dire->type]);
4887+
4888+ if (filldir(dirent, dire->name, dire->size + 1,
4889+ file->f_pos, SQUASHFS_MK_VFS_INODE(
4890+ dirh.start_block, dire->offset),
4891+ squashfs_filetype_table[dire->type])
4892+ < 0) {
4893+ TRACE("Filldir returned less than 0\n");
4894+ goto finish;
4895+ }
4896+ file->f_pos = length;
4897+ }
4898+ }
4899+
4900+finish:
4901+ kfree(dire);
4902+ return 0;
4903+
4904+failed_read:
4905+ ERROR("Unable to read directory block [%llx:%x]\n", next_block,
4906+ next_offset);
4907+ kfree(dire);
4908+ return 0;
4909+}
4910+
4911+
4912+static struct dentry *squashfs_lookup_2(struct inode *i, struct dentry *dentry,
4913+ struct nameidata *nd)
4914+{
4915+ const unsigned char *name = dentry->d_name.name;
4916+ int len = dentry->d_name.len;
4917+ struct inode *inode = NULL;
4918+ struct squashfs_sb_info *msblk = i->i_sb->s_fs_info;
4919+ struct squashfs_super_block *sblk = &msblk->sblk;
4920+ long long next_block = SQUASHFS_I(i)->start_block +
4921+ sblk->directory_table_start;
4922+ int next_offset = SQUASHFS_I(i)->offset, length = 0,
4923+ dir_count;
4924+ struct squashfs_dir_header_2 dirh;
4925+ struct squashfs_dir_entry_2 *dire;
4926+ int sorted = sblk->s_major == 2 && sblk->s_minor >= 1;
4927+
4928+ TRACE("Entered squashfs_lookup_2 [%llx:%x]\n", next_block, next_offset);
4929+
4930+ if (!(dire = kmalloc(sizeof(struct squashfs_dir_entry) +
4931+ SQUASHFS_NAME_LEN + 1, GFP_KERNEL))) {
4932+ ERROR("Failed to allocate squashfs_dir_entry\n");
4933+ goto exit_loop;
4934+ }
4935+
4936+ if (len > SQUASHFS_NAME_LEN)
4937+ goto exit_loop;
4938+
4939+ length = get_dir_index_using_name(i->i_sb, &next_block, &next_offset,
4940+ SQUASHFS_I(i)->u.s2.directory_index_start,
4941+ SQUASHFS_I(i)->u.s2.directory_index_offset,
4942+ SQUASHFS_I(i)->u.s2.directory_index_count, name,
4943+ len);
4944+
4945+ while (length < i_size_read(i)) {
4946+ /* read directory header */
4947+ if (msblk->swap) {
4948+ struct squashfs_dir_header_2 sdirh;
4949+ if (!squashfs_get_cached_block(i->i_sb, (char *) &sdirh,
4950+ next_block, next_offset, sizeof(sdirh),
4951+ &next_block, &next_offset))
4952+ goto failed_read;
4953+
4954+ length += sizeof(sdirh);
4955+ SQUASHFS_SWAP_DIR_HEADER_2(&dirh, &sdirh);
4956+ } else {
4957+ if (!squashfs_get_cached_block(i->i_sb, (char *) &dirh,
4958+ next_block, next_offset, sizeof(dirh),
4959+ &next_block, &next_offset))
4960+ goto failed_read;
4961+
4962+ length += sizeof(dirh);
4963+ }
4964+
4965+ dir_count = dirh.count + 1;
4966+ while (dir_count--) {
4967+ if (msblk->swap) {
4968+ struct squashfs_dir_entry_2 sdire;
4969+ if (!squashfs_get_cached_block(i->i_sb, (char *)
4970+ &sdire, next_block,next_offset,
4971+ sizeof(sdire), &next_block,
4972+ &next_offset))
4973+ goto failed_read;
4974+
4975+ length += sizeof(sdire);
4976+ SQUASHFS_SWAP_DIR_ENTRY_2(dire, &sdire);
4977+ } else {
4978+ if (!squashfs_get_cached_block(i->i_sb, (char *)
4979+ dire, next_block,next_offset,
4980+ sizeof(*dire), &next_block,
4981+ &next_offset))
4982+ goto failed_read;
4983+
4984+ length += sizeof(*dire);
4985+ }
4986+
4987+ if (!squashfs_get_cached_block(i->i_sb, dire->name,
4988+ next_block, next_offset, dire->size + 1,
4989+ &next_block, &next_offset))
4990+ goto failed_read;
4991+
4992+ length += dire->size + 1;
4993+
4994+ if (sorted && name[0] < dire->name[0])
4995+ goto exit_loop;
4996+
4997+ if ((len == dire->size + 1) && !strncmp(name,
4998+ dire->name, len)) {
4999+ squashfs_inode_t ino =
5000+ SQUASHFS_MKINODE(dirh.start_block,
5001+ dire->offset);
5002+ unsigned int inode_number = SQUASHFS_MK_VFS_INODE(dirh.start_block,
5003+ dire->offset);
5004+
5005+ TRACE("calling squashfs_iget for directory "
5006+ "entry %s, inode %x:%x, %lld\n", name,
5007+ dirh.start_block, dire->offset, ino);
5008+
5009+ inode = squashfs_iget(i->i_sb, ino, inode_number);
5010+
5011+ goto exit_loop;
5012+ }
5013+ }
5014+ }
5015+
5016+exit_loop:
5017+ kfree(dire);
5018+ d_add(dentry, inode);
5019+ return ERR_PTR(0);
5020+
5021+failed_read:
5022+ ERROR("Unable to read directory block [%llx:%x]\n", next_block,
5023+ next_offset);
5024+ goto exit_loop;
5025+}
5026+
5027+
5028+int squashfs_2_0_supported(struct squashfs_sb_info *msblk)
5029+{
5030+ struct squashfs_super_block *sblk = &msblk->sblk;
5031+
5032+ msblk->read_inode = squashfs_read_inode_2;
5033+ msblk->read_fragment_index_table = read_fragment_index_table_2;
5034+
5035+ sblk->bytes_used = sblk->bytes_used_2;
5036+ sblk->uid_start = sblk->uid_start_2;
5037+ sblk->guid_start = sblk->guid_start_2;
5038+ sblk->inode_table_start = sblk->inode_table_start_2;
5039+ sblk->directory_table_start = sblk->directory_table_start_2;
5040+ sblk->fragment_table_start = sblk->fragment_table_start_2;
5041+
5042+ return 1;
5043+}
5044diff -uNr a/fs/squashfs/squashfs.h b/fs/squashfs/squashfs.h
5045--- a/fs/squashfs/squashfs.h 1969-12-31 16:00:00.000000000 -0800
5046+++ b/fs/squashfs/squashfs.h 2008-08-13 16:14:50.000000000 -0700
5047@@ -0,0 +1,122 @@
5048+/*
5049+ * Squashfs - a compressed read only filesystem for Linux
5050+ *
5051+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
5052+ * Phillip Lougher <phillip@lougher.demon.co.uk>
5053+ *
5054+ * This program is free software; you can redistribute it and/or
5055+ * modify it under the terms of the GNU General Public License
5056+ * as published by the Free Software Foundation; either version 2,
5057+ * or (at your option) any later version.
5058+ *
5059+ * This program is distributed in the hope that it will be useful,
5060+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
5061+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5062+ * GNU General Public License for more details.
5063+ *
5064+ * You should have received a copy of the GNU General Public License
5065+ * along with this program; if not, write to the Free Software
5066+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
5067+ *
5068+ * squashfs.h
5069+ */
5070+
5071+#ifdef CONFIG_SQUASHFS_1_0_COMPATIBILITY
5072+#undef CONFIG_SQUASHFS_1_0_COMPATIBILITY
5073+#endif
5074+
5075+#ifdef SQUASHFS_TRACE
5076+#define TRACE(s, args...) printk(KERN_NOTICE "SQUASHFS: "s, ## args)
5077+#else
5078+#define TRACE(s, args...) {}
5079+#endif
5080+
5081+#define ERROR(s, args...) printk(KERN_ERR "SQUASHFS error: "s, ## args)
5082+
5083+#define SERROR(s, args...) do { \
5084+ if (!silent) \
5085+ printk(KERN_ERR "SQUASHFS error: "s, ## args);\
5086+ } while(0)
5087+
5088+#define WARNING(s, args...) printk(KERN_WARNING "SQUASHFS: "s, ## args)
5089+
5090+static inline struct squashfs_inode_info *SQUASHFS_I(struct inode *inode)
5091+{
5092+ return list_entry(inode, struct squashfs_inode_info, vfs_inode);
5093+}
5094+
5095+/* block.c */
5096+extern unsigned int squashfs_read_data(struct super_block *, char *,
5097+ long long, unsigned int, long long *, int);
5098+extern int squashfs_get_cached_block(struct super_block *, void *,
5099+ long long, unsigned int, int, long long *, unsigned int *);
5100+
5101+/* cache.c */
5102+extern struct squashfs_cache_entry *squashfs_cache_get(struct super_block *,
5103+ struct squashfs_cache *, long long, int);
5104+extern void squashfs_cache_put(struct squashfs_cache *,
5105+ struct squashfs_cache_entry *);
5106+extern void squashfs_cache_delete(struct squashfs_cache *);
5107+extern struct squashfs_cache *squashfs_cache_init(char *, int, int, int);
5108+
5109+/* export.c */
5110+extern int read_inode_lookup_table(struct super_block *);
5111+
5112+/* file.c */
5113+extern long long read_blocklist(struct inode *, int, int, char *,
5114+ unsigned short **, unsigned int *);
5115+
5116+/* fragment.c */
5117+extern int get_fragment_location(struct super_block *, unsigned int,
5118+ long long *, unsigned int *);
5119+extern void release_cached_fragment(struct squashfs_sb_info *,
5120+ struct squashfs_cache_entry *);
5121+extern struct squashfs_cache_entry *get_cached_fragment(struct super_block *,
5122+ long long, int);
5123+extern int read_fragment_index_table(struct super_block *);
5124+
5125+/* id.c */
5126+extern int get_id(struct super_block *, unsigned int, unsigned int *);
5127+extern int read_id_index_table(struct super_block *);
5128+
5129+/* inode.c */
5130+extern struct inode *squashfs_iget(struct super_block *, squashfs_inode_t,
5131+ unsigned int);
5132+extern int squashfs_read_inode(struct inode *, squashfs_inode_t);
5133+
5134+/*
5135+ * Inodes and files operations
5136+ */
5137+
5138+/* dir.c */
5139+extern const struct file_operations squashfs_dir_ops;
5140+
5141+/* export.c */
5142+extern const struct export_operations squashfs_export_ops;
5143+
5144+/* file.c */
5145+extern const struct address_space_operations squashfs_aops;
5146+
5147+/* namei.c */
5148+extern const struct inode_operations squashfs_dir_inode_ops;
5149+
5150+/* symlink.c */
5151+extern const struct address_space_operations squashfs_symlink_aops;
5152+
5153+#ifdef CONFIG_SQUASHFS_1_0_COMPATIBILITY
5154+extern int squashfs_1_0_supported(struct squashfs_sb_info *msblk);
5155+#else
5156+static inline int squashfs_1_0_supported(struct squashfs_sb_info *msblk)
5157+{
5158+ return 0;
5159+}
5160+#endif
5161+
5162+#ifdef CONFIG_SQUASHFS_2_0_COMPATIBILITY
5163+extern int squashfs_2_0_supported(struct squashfs_sb_info *msblk);
5164+#else
5165+static inline int squashfs_2_0_supported(struct squashfs_sb_info *msblk)
5166+{
5167+ return 0;
5168+}
5169+#endif
5170diff -uNr a/fs/squashfs/super.c b/fs/squashfs/super.c
5171--- a/fs/squashfs/super.c 1969-12-31 16:00:00.000000000 -0800
5172+++ b/fs/squashfs/super.c 2008-08-13 16:14:50.000000000 -0700
5173@@ -0,0 +1,381 @@
5174+/*
5175+ * Squashfs - a compressed read only filesystem for Linux
5176+ *
5177+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
5178+ * Phillip Lougher <phillip@lougher.demon.co.uk>
5179+ *
5180+ * This program is free software; you can redistribute it and/or
5181+ * modify it under the terms of the GNU General Public License
5182+ * as published by the Free Software Foundation; either version 2,
5183+ * or (at your option) any later version.
5184+ *
5185+ * This program is distributed in the hope that it will be useful,
5186+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
5187+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5188+ * GNU General Public License for more details.
5189+ *
5190+ * You should have received a copy of the GNU General Public License
5191+ * along with this program; if not, write to the Free Software
5192+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
5193+ *
5194+ * super.c
5195+ */
5196+
5197+#include <linux/squashfs_fs.h>
5198+#include <linux/module.h>
5199+#include <linux/zlib.h>
5200+#include <linux/fs.h>
5201+#include <linux/squashfs_fs_sb.h>
5202+#include <linux/squashfs_fs_i.h>
5203+#include <linux/buffer_head.h>
5204+#include <linux/vfs.h>
5205+#include <linux/vmalloc.h>
5206+#include <linux/spinlock.h>
5207+#include <linux/smp_lock.h>
5208+#include <linux/exportfs.h>
5209+
5210+#include "squashfs.h"
5211+
5212+static struct file_system_type squashfs_fs_type;
5213+static struct super_operations squashfs_super_ops;
5214+
5215+static int supported_squashfs_filesystem(struct squashfs_sb_info *msblk, int silent)
5216+{
5217+ struct squashfs_super_block *sblk = &msblk->sblk;
5218+
5219+ msblk->read_inode = squashfs_read_inode;
5220+ msblk->read_blocklist = read_blocklist;
5221+ msblk->read_fragment_index_table = read_fragment_index_table;
5222+
5223+ if (sblk->s_major == 1) {
5224+ if (!squashfs_1_0_supported(msblk)) {
5225+ SERROR("Major/Minor mismatch, Squashfs 1.0 filesystems "
5226+ "are unsupported\n");
5227+ SERROR("Please recompile with Squashfs 1.0 support enabled\n");
5228+ return 0;
5229+ }
5230+ } else if (sblk->s_major == 2) {
5231+ if (!squashfs_2_0_supported(msblk)) {
5232+ SERROR("Major/Minor mismatch, Squashfs 2.0 filesystems "
5233+ "are unsupported\n");
5234+ SERROR("Please recompile with Squashfs 2.0 support enabled\n");
5235+ return 0;
5236+ }
5237+ } else if(sblk->s_major != SQUASHFS_MAJOR || sblk->s_minor >
5238+ SQUASHFS_MINOR) {
5239+ SERROR("Major/Minor mismatch, trying to mount newer %d.%d "
5240+ "filesystem\n", sblk->s_major, sblk->s_minor);
5241+ SERROR("Please update your kernel\n");
5242+ return 0;
5243+ }
5244+
5245+ return 1;
5246+}
5247+
5248+
5249+static int squashfs_fill_super(struct super_block *s, void *data, int silent)
5250+{
5251+ struct squashfs_sb_info *msblk;
5252+ struct squashfs_super_block *sblk;
5253+ char b[BDEVNAME_SIZE];
5254+ struct inode *root;
5255+
5256+ TRACE("Entered squashfs_fill_superblock\n");
5257+
5258+ s->s_fs_info = kzalloc(sizeof(struct squashfs_sb_info), GFP_KERNEL);
5259+ if (s->s_fs_info == NULL) {
5260+ ERROR("Failed to allocate superblock\n");
5261+ goto failure;
5262+ }
5263+ msblk = s->s_fs_info;
5264+
5265+ msblk->stream.workspace = vmalloc(zlib_inflate_workspacesize());
5266+ if (msblk->stream.workspace == NULL) {
5267+ ERROR("Failed to allocate zlib workspace\n");
5268+ goto failure;
5269+ }
5270+ sblk = &msblk->sblk;
5271+
5272+ msblk->devblksize = sb_min_blocksize(s, BLOCK_SIZE);
5273+ msblk->devblksize_log2 = ffz(~msblk->devblksize);
5274+
5275+ mutex_init(&msblk->read_data_mutex);
5276+ mutex_init(&msblk->read_page_mutex);
5277+ mutex_init(&msblk->meta_index_mutex);
5278+
5279+ /* sblk->bytes_used is checked in squashfs_read_data to ensure reads are not
5280+ * beyond filesystem end. As we're using squashfs_read_data to read sblk here,
5281+ * first set sblk->bytes_used to a useful value */
5282+ sblk->bytes_used = sizeof(struct squashfs_super_block);
5283+ if (!squashfs_read_data(s, (char *) sblk, SQUASHFS_START,
5284+ sizeof(struct squashfs_super_block) |
5285+ SQUASHFS_COMPRESSED_BIT_BLOCK, NULL, sizeof(struct squashfs_super_block))) {
5286+ SERROR("unable to read superblock\n");
5287+ goto failed_mount;
5288+ }
5289+
5290+ /* Check it is a SQUASHFS superblock */
5291+ if ((s->s_magic = sblk->s_magic) != SQUASHFS_MAGIC) {
5292+ if (sblk->s_magic == SQUASHFS_MAGIC_SWAP) {
5293+ struct squashfs_super_block ssblk;
5294+
5295+ WARNING("Mounting a different endian SQUASHFS filesystem on %s\n",
5296+ bdevname(s->s_bdev, b));
5297+
5298+ //SQUASHFS_SWAP_SUPER_BLOCK(&ssblk, sblk);
5299+ memcpy(sblk, &ssblk, sizeof(struct squashfs_super_block));
5300+ msblk->swap = 1;
5301+ } else {
5302+ SERROR("Can't find a SQUASHFS superblock on %s\n",
5303+ bdevname(s->s_bdev, b));
5304+ goto failed_mount;
5305+ }
5306+ }
5307+
5308+ /* Check the MAJOR & MINOR versions */
5309+ if(!supported_squashfs_filesystem(msblk, silent))
5310+ goto failed_mount;
5311+
5312+ /* Check the filesystem does not extend beyond the end of the
5313+ block device */
5314+ if(sblk->bytes_used < 0 || sblk->bytes_used > i_size_read(s->s_bdev->bd_inode))
5315+ goto failed_mount;
5316+
5317+ /* Check the root inode for sanity */
5318+ if (SQUASHFS_INODE_OFFSET(sblk->root_inode) > SQUASHFS_METADATA_SIZE)
5319+ goto failed_mount;
5320+
5321+ TRACE("Found valid superblock on %s\n", bdevname(s->s_bdev, b));
5322+ TRACE("Inodes are %scompressed\n", SQUASHFS_UNCOMPRESSED_INODES(sblk->flags)
5323+ ? "un" : "");
5324+ TRACE("Data is %scompressed\n", SQUASHFS_UNCOMPRESSED_DATA(sblk->flags)
5325+ ? "un" : "");
5326+ TRACE("Check data is %spresent in the filesystem\n",
5327+ SQUASHFS_CHECK_DATA(sblk->flags) ? "" : "not ");
5328+ TRACE("Filesystem size %lld bytes\n", sblk->bytes_used);
5329+ TRACE("Block size %d\n", sblk->block_size);
5330+ TRACE("Number of inodes %d\n", sblk->inodes);
5331+ if (sblk->s_major > 1)
5332+ TRACE("Number of fragments %d\n", sblk->fragments);
5333+ TRACE("Number of ids %d\n", sblk->no_ids);
5334+ TRACE("sblk->inode_table_start %llx\n", sblk->inode_table_start);
5335+ TRACE("sblk->directory_table_start %llx\n", sblk->directory_table_start);
5336+ if (sblk->s_major > 1)
5337+ TRACE("sblk->fragment_table_start %llx\n", sblk->fragment_table_start);
5338+ TRACE("sblk->id_table_start %llx\n", sblk->id_table_start);
5339+
5340+ s->s_maxbytes = MAX_LFS_FILESIZE;
5341+ s->s_flags |= MS_RDONLY;
5342+ s->s_op = &squashfs_super_ops;
5343+
5344+ msblk->block_cache = squashfs_cache_init("metadata", SQUASHFS_CACHED_BLKS,
5345+ SQUASHFS_METADATA_SIZE, 0);
5346+ if (msblk->block_cache == NULL)
5347+ goto failed_mount;
5348+
5349+ /* Allocate read_page block */
5350+ msblk->read_page = vmalloc(sblk->block_size);
5351+ if (msblk->read_page == NULL) {
5352+ ERROR("Failed to allocate read_page block\n");
5353+ goto failed_mount;
5354+ }
5355+
5356+ /* Allocate and read id index table */
5357+ if (read_id_index_table(s) == 0)
5358+ goto failed_mount;
5359+
5360+ if (sblk->s_major == 1 && squashfs_1_0_supported(msblk))
5361+ goto allocate_root;
5362+
5363+ msblk->fragment_cache = squashfs_cache_init("fragment",
5364+ SQUASHFS_CACHED_FRAGMENTS, sblk->block_size, 1);
5365+ if (msblk->fragment_cache == NULL)
5366+ goto failed_mount;
5367+
5368+ /* Allocate and read fragment index table */
5369+ if (msblk->read_fragment_index_table(s) == 0)
5370+ goto failed_mount;
5371+
5372+ if(sblk->s_major < 3 || sblk->lookup_table_start == SQUASHFS_INVALID_BLK)
5373+ goto allocate_root;
5374+
5375+ /* Allocate and read inode lookup table */
5376+ if (read_inode_lookup_table(s) == 0)
5377+ goto failed_mount;
5378+
5379+ s->s_export_op = &squashfs_export_ops;
5380+
5381+allocate_root:
5382+ root = new_inode(s);
5383+ if ((msblk->read_inode)(root, sblk->root_inode) == 0)
5384+ goto failed_mount;
5385+ insert_inode_hash(root);
5386+
5387+ s->s_root = d_alloc_root(root);
5388+ if (s->s_root == NULL) {
5389+ ERROR("Root inode create failed\n");
5390+ iput(root);
5391+ goto failed_mount;
5392+ }
5393+
5394+ TRACE("Leaving squashfs_fill_super\n");
5395+ return 0;
5396+
5397+failed_mount:
5398+ kfree(msblk->inode_lookup_table);
5399+ kfree(msblk->fragment_index);
5400+ squashfs_cache_delete(msblk->fragment_cache);
5401+ kfree(msblk->id_table);
5402+ vfree(msblk->read_page);
5403+ squashfs_cache_delete(msblk->block_cache);
5404+ kfree(msblk->fragment_index_2);
5405+ vfree(msblk->stream.workspace);
5406+ kfree(s->s_fs_info);
5407+ s->s_fs_info = NULL;
5408+ return -EINVAL;
5409+
5410+failure:
5411+ return -ENOMEM;
5412+}
5413+
5414+
5415+static int squashfs_statfs(struct dentry *dentry, struct kstatfs *buf)
5416+{
5417+ struct squashfs_sb_info *msblk = dentry->d_sb->s_fs_info;
5418+ struct squashfs_super_block *sblk = &msblk->sblk;
5419+
5420+ TRACE("Entered squashfs_statfs\n");
5421+
5422+ buf->f_type = SQUASHFS_MAGIC;
5423+ buf->f_bsize = sblk->block_size;
5424+ buf->f_blocks = ((sblk->bytes_used - 1) >> sblk->block_log) + 1;
5425+ buf->f_bfree = buf->f_bavail = 0;
5426+ buf->f_files = sblk->inodes;
5427+ buf->f_ffree = 0;
5428+ buf->f_namelen = SQUASHFS_NAME_LEN;
5429+
5430+ return 0;
5431+}
5432+
5433+
5434+static int squashfs_remount(struct super_block *s, int *flags, char *data)
5435+{
5436+ *flags |= MS_RDONLY;
5437+ return 0;
5438+}
5439+
5440+
5441+static void squashfs_put_super(struct super_block *s)
5442+{
5443+ if (s->s_fs_info) {
5444+ struct squashfs_sb_info *sbi = s->s_fs_info;
5445+ squashfs_cache_delete(sbi->block_cache);
5446+ squashfs_cache_delete(sbi->fragment_cache);
5447+ vfree(sbi->read_page);
5448+ kfree(sbi->id_table);
5449+ kfree(sbi->fragment_index);
5450+ kfree(sbi->fragment_index_2);
5451+ kfree(sbi->meta_index);
5452+ vfree(sbi->stream.workspace);
5453+ kfree(s->s_fs_info);
5454+ s->s_fs_info = NULL;
5455+ }
5456+}
5457+
5458+
5459+static int squashfs_get_sb(struct file_system_type *fs_type, int flags,
5460+ const char *dev_name, void *data, struct vfsmount *mnt)
5461+{
5462+ return get_sb_bdev(fs_type, flags, dev_name, data, squashfs_fill_super,
5463+ mnt);
5464+}
5465+
5466+
5467+static struct kmem_cache * squashfs_inode_cachep;
5468+
5469+
5470+static void init_once(void *foo)
5471+{
5472+ struct squashfs_inode_info *ei = foo;
5473+
5474+ inode_init_once(&ei->vfs_inode);
5475+}
5476+
5477+
5478+static int __init init_inodecache(void)
5479+{
5480+ squashfs_inode_cachep = kmem_cache_create("squashfs_inode_cache",
5481+ sizeof(struct squashfs_inode_info), 0,
5482+ SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT, init_once);
5483+ if (squashfs_inode_cachep == NULL)
5484+ return -ENOMEM;
5485+ return 0;
5486+}
5487+
5488+
5489+static void destroy_inodecache(void)
5490+{
5491+ kmem_cache_destroy(squashfs_inode_cachep);
5492+}
5493+
5494+
5495+static int __init init_squashfs_fs(void)
5496+{
5497+ int err = init_inodecache();
5498+ if (err)
5499+ goto out;
5500+
5501+ printk(KERN_INFO "squashfs: version 4.0-CVS (2008/07/27) "
5502+ "Phillip Lougher\n");
5503+
5504+ err = register_filesystem(&squashfs_fs_type);
5505+ if (err)
5506+ destroy_inodecache();
5507+
5508+out:
5509+ return err;
5510+}
5511+
5512+
5513+static void __exit exit_squashfs_fs(void)
5514+{
5515+ unregister_filesystem(&squashfs_fs_type);
5516+ destroy_inodecache();
5517+}
5518+
5519+
5520+static struct inode *squashfs_alloc_inode(struct super_block *sb)
5521+{
5522+ struct squashfs_inode_info *ei;
5523+ ei = kmem_cache_alloc(squashfs_inode_cachep, GFP_KERNEL);
5524+ return ei ? &ei->vfs_inode : NULL;
5525+}
5526+
5527+
5528+static void squashfs_destroy_inode(struct inode *inode)
5529+{
5530+ kmem_cache_free(squashfs_inode_cachep, SQUASHFS_I(inode));
5531+}
5532+
5533+
5534+static struct file_system_type squashfs_fs_type = {
5535+ .owner = THIS_MODULE,
5536+ .name = "squashfs",
5537+ .get_sb = squashfs_get_sb,
5538+ .kill_sb = kill_block_super,
5539+ .fs_flags = FS_REQUIRES_DEV
5540+};
5541+
5542+static struct super_operations squashfs_super_ops = {
5543+ .alloc_inode = squashfs_alloc_inode,
5544+ .destroy_inode = squashfs_destroy_inode,
5545+ .statfs = squashfs_statfs,
5546+ .put_super = squashfs_put_super,
5547+ .remount_fs = squashfs_remount
5548+};
5549+
5550+module_init(init_squashfs_fs);
5551+module_exit(exit_squashfs_fs);
5552+MODULE_DESCRIPTION("squashfs 4.0-CVS, a compressed read-only filesystem");
5553+MODULE_AUTHOR("Phillip Lougher <phillip@lougher.demon.co.uk>");
5554+MODULE_LICENSE("GPL");
5555diff -uNr a/fs/squashfs/symlink.c b/fs/squashfs/symlink.c
5556--- a/fs/squashfs/symlink.c 1969-12-31 16:00:00.000000000 -0800
5557+++ b/fs/squashfs/symlink.c 2008-08-13 16:14:50.000000000 -0700
5558@@ -0,0 +1,85 @@
5559+/*
5560+ * Squashfs - a compressed read only filesystem for Linux
5561+ *
5562+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
5563+ * Phillip Lougher <phillip@lougher.demon.co.uk>
5564+ *
5565+ * This program is free software; you can redistribute it and/or
5566+ * modify it under the terms of the GNU General Public License
5567+ * as published by the Free Software Foundation; either version 2,
5568+ * or (at your option) any later version.
5569+ *
5570+ * This program is distributed in the hope that it will be useful,
5571+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
5572+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5573+ * GNU General Public License for more details.
5574+ *
5575+ * You should have received a copy of the GNU General Public License
5576+ * along with this program; if not, write to the Free Software
5577+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
5578+ *
5579+ * symlink.c
5580+ */
5581+
5582+#include <linux/fs.h>
5583+#include <linux/vfs.h>
5584+#include <linux/zlib.h>
5585+#include <linux/buffer_head.h>
5586+#include <linux/squashfs_fs.h>
5587+#include <linux/squashfs_fs_sb.h>
5588+#include <linux/squashfs_fs_i.h>
5589+
5590+#include "squashfs.h"
5591+
5592+static int squashfs_symlink_readpage(struct file *file, struct page *page)
5593+{
5594+ struct inode *inode = page->mapping->host;
5595+ int index = page->index << PAGE_CACHE_SHIFT;
5596+ long long block = SQUASHFS_I(inode)->start_block;
5597+ int offset = SQUASHFS_I(inode)->offset;
5598+ void *pageaddr = kmap(page);
5599+ int length, bytes, avail_bytes;
5600+
5601+ TRACE("Entered squashfs_symlink_readpage, page index %ld, start block "
5602+ "%llx, offset %x\n", page->index,
5603+ SQUASHFS_I(inode)->start_block,
5604+ SQUASHFS_I(inode)->offset);
5605+
5606+ for (length = 0; length < index; length += bytes) {
5607+ bytes = squashfs_get_cached_block(inode->i_sb, NULL, block,
5608+ offset, PAGE_CACHE_SIZE, &block, &offset);
5609+ if (bytes == 0) {
5610+ ERROR("Unable to read symbolic link [%llx:%x]\n",
5611+ block, offset);
5612+ goto skip_read;
5613+ }
5614+ }
5615+
5616+ if (length != index) {
5617+ ERROR("(squashfs_symlink_readpage) length != index\n");
5618+ bytes = 0;
5619+ goto skip_read;
5620+ }
5621+
5622+ avail_bytes = min_t(int, i_size_read(inode) - length, PAGE_CACHE_SIZE);
5623+
5624+ bytes = squashfs_get_cached_block(inode->i_sb, pageaddr, block, offset,
5625+ avail_bytes, &block, &offset);
5626+ if (bytes == 0)
5627+ ERROR("Unable to read symbolic link [%llx:%x]\n", block,
5628+ offset);
5629+
5630+skip_read:
5631+ memset(pageaddr + bytes, 0, PAGE_CACHE_SIZE - bytes);
5632+ kunmap(page);
5633+ flush_dcache_page(page);
5634+ SetPageUptodate(page);
5635+ unlock_page(page);
5636+
5637+ return 0;
5638+}
5639+
5640+
5641+const struct address_space_operations squashfs_symlink_aops = {
5642+ .readpage = squashfs_symlink_readpage
5643+};
5644diff -uNr a/include/linux/squashfs_fs.h b/include/linux/squashfs_fs.h
5645--- a/include/linux/squashfs_fs.h 1969-12-31 16:00:00.000000000 -0800
5646+++ b/include/linux/squashfs_fs.h 2008-08-13 16:16:05.000000000 -0700
5647@@ -0,0 +1,949 @@
5648+#ifndef SQUASHFS_FS
5649+#define SQUASHFS_FS
5650+/*
5651+ * Squashfs
5652+ *
5653+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
5654+ * Phillip Lougher <phillip@lougher.demon.co.uk>
5655+ *
5656+ * This program is free software; you can redistribute it and/or
5657+ * modify it under the terms of the GNU General Public License
5658+ * as published by the Free Software Foundation; either version 2,
5659+ * or (at your option) any later version.
5660+ *
5661+ * This program is distributed in the hope that it will be useful,
5662+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
5663+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5664+ * GNU General Public License for more details.
5665+ *
5666+ * You should have received a copy of the GNU General Public License
5667+ * along with this program; if not, write to the Free Software
5668+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
5669+ *
5670+ * squashfs_fs.h
5671+ */
5672+
5673+#if 0
5674+#ifndef CONFIG_SQUASHFS_2_0_COMPATIBILITY
5675+#define CONFIG_SQUASHFS_2_0_COMPATIBILITY
5676+#endif
5677+#endif
5678+
5679+#define SQUASHFS_CACHED_FRAGMENTS CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE
5680+#define SQUASHFS_MAJOR 4
5681+#define SQUASHFS_MINOR 0
5682+#define SQUASHFS_MAGIC 0x73717368
5683+#define SQUASHFS_MAGIC_SWAP 0x68737173
5684+#define SQUASHFS_START 0
5685+
5686+/* size of metadata (inode and directory) blocks */
5687+#define SQUASHFS_METADATA_SIZE 8192
5688+#define SQUASHFS_METADATA_LOG 13
5689+
5690+/* default size of data blocks */
5691+#define SQUASHFS_FILE_SIZE 131072
5692+#define SQUASHFS_FILE_LOG 17
5693+
5694+#define SQUASHFS_FILE_MAX_SIZE 1048576
5695+
5696+/* Max number of uids and gids */
5697+#define SQUASHFS_IDS 65536
5698+
5699+/* Max length of filename (not 255) */
5700+#define SQUASHFS_NAME_LEN 256
5701+
5702+#define SQUASHFS_INVALID ((long long) 0xffffffffffff)
5703+#define SQUASHFS_INVALID_FRAG ((unsigned int) 0xffffffff)
5704+#define SQUASHFS_INVALID_BLK ((long long) -1)
5705+#define SQUASHFS_USED_BLK ((long long) -2)
5706+
5707+/* Filesystem flags */
5708+#define SQUASHFS_NOI 0
5709+#define SQUASHFS_NOD 1
5710+#define SQUASHFS_CHECK 2
5711+#define SQUASHFS_NOF 3
5712+#define SQUASHFS_NO_FRAG 4
5713+#define SQUASHFS_ALWAYS_FRAG 5
5714+#define SQUASHFS_DUPLICATE 6
5715+#define SQUASHFS_EXPORT 7
5716+
5717+#define SQUASHFS_BIT(flag, bit) ((flag >> bit) & 1)
5718+
5719+#define SQUASHFS_UNCOMPRESSED_INODES(flags) SQUASHFS_BIT(flags, \
5720+ SQUASHFS_NOI)
5721+
5722+#define SQUASHFS_UNCOMPRESSED_DATA(flags) SQUASHFS_BIT(flags, \
5723+ SQUASHFS_NOD)
5724+
5725+#define SQUASHFS_UNCOMPRESSED_FRAGMENTS(flags) SQUASHFS_BIT(flags, \
5726+ SQUASHFS_NOF)
5727+
5728+#define SQUASHFS_NO_FRAGMENTS(flags) SQUASHFS_BIT(flags, \
5729+ SQUASHFS_NO_FRAG)
5730+
5731+#define SQUASHFS_ALWAYS_FRAGMENTS(flags) SQUASHFS_BIT(flags, \
5732+ SQUASHFS_ALWAYS_FRAG)
5733+
5734+#define SQUASHFS_DUPLICATES(flags) SQUASHFS_BIT(flags, \
5735+ SQUASHFS_DUPLICATE)
5736+
5737+#define SQUASHFS_EXPORTABLE(flags) SQUASHFS_BIT(flags, \
5738+ SQUASHFS_EXPORT)
5739+
5740+#define SQUASHFS_CHECK_DATA(flags) SQUASHFS_BIT(flags, \
5741+ SQUASHFS_CHECK)
5742+
5743+#define SQUASHFS_MKFLAGS(noi, nod, check_data, nof, no_frag, always_frag, \
5744+ duplicate_checking, exportable) (noi | (nod << 1) | (check_data << 2) \
5745+ | (nof << 3) | (no_frag << 4) | (always_frag << 5) | \
5746+ (duplicate_checking << 6) | (exportable << 7))
5747+
5748+/* Max number of types and file types */
5749+#define SQUASHFS_DIR_TYPE 1
5750+#define SQUASHFS_FILE_TYPE 2
5751+#define SQUASHFS_SYMLINK_TYPE 3
5752+#define SQUASHFS_BLKDEV_TYPE 4
5753+#define SQUASHFS_CHRDEV_TYPE 5
5754+#define SQUASHFS_FIFO_TYPE 6
5755+#define SQUASHFS_SOCKET_TYPE 7
5756+#define SQUASHFS_LDIR_TYPE 8
5757+#define SQUASHFS_LREG_TYPE 9
5758+
5759+/* 1.0 filesystem type definitions */
5760+#define SQUASHFS_TYPES 5
5761+#define SQUASHFS_IPC_TYPE 0
5762+
5763+/* Flag whether block is compressed or uncompressed, bit is set if block is
5764+ * uncompressed */
5765+#define SQUASHFS_COMPRESSED_BIT (1 << 15)
5766+
5767+#define SQUASHFS_COMPRESSED_SIZE(B) (((B) & ~SQUASHFS_COMPRESSED_BIT) ? \
5768+ (B) & ~SQUASHFS_COMPRESSED_BIT : SQUASHFS_COMPRESSED_BIT)
5769+
5770+#define SQUASHFS_COMPRESSED(B) (!((B) & SQUASHFS_COMPRESSED_BIT))
5771+
5772+#define SQUASHFS_COMPRESSED_BIT_BLOCK (1 << 24)
5773+
5774+#define SQUASHFS_COMPRESSED_SIZE_BLOCK(B) ((B) & \
5775+ ~SQUASHFS_COMPRESSED_BIT_BLOCK)
5776+
5777+#define SQUASHFS_COMPRESSED_BLOCK(B) (!((B) & SQUASHFS_COMPRESSED_BIT_BLOCK))
5778+
5779+/*
5780+ * Inode number ops. Inodes consist of a compressed block number, and an
5781+ * uncompressed offset within that block
5782+ */
5783+#define SQUASHFS_INODE_BLK(a) ((unsigned int) ((a) >> 16))
5784+
5785+#define SQUASHFS_INODE_OFFSET(a) ((unsigned int) ((a) & 0xffff))
5786+
5787+#define SQUASHFS_MKINODE(A, B) ((squashfs_inode_t)(((squashfs_inode_t) (A)\
5788+ << 16) + (B)))
5789+
5790+/* Compute 32 bit VFS inode number from squashfs inode number */
5791+#define SQUASHFS_MK_VFS_INODE(a, b) ((unsigned int) (((a) << 8) + \
5792+ ((b) >> 2) + 1))
5793+/* XXX */
5794+
5795+/* Translate between VFS mode and squashfs mode */
5796+#define SQUASHFS_MODE(a) ((a) & 0xfff)
5797+
5798+/* fragment and fragment table defines */
5799+#define SQUASHFS_FRAGMENT_BYTES(A) ((A) * sizeof(struct squashfs_fragment_entry))
5800+
5801+#define SQUASHFS_FRAGMENT_INDEX(A) (SQUASHFS_FRAGMENT_BYTES(A) / \
5802+ SQUASHFS_METADATA_SIZE)
5803+
5804+#define SQUASHFS_FRAGMENT_INDEX_OFFSET(A) (SQUASHFS_FRAGMENT_BYTES(A) % \
5805+ SQUASHFS_METADATA_SIZE)
5806+
5807+#define SQUASHFS_FRAGMENT_INDEXES(A) ((SQUASHFS_FRAGMENT_BYTES(A) + \
5808+ SQUASHFS_METADATA_SIZE - 1) / \
5809+ SQUASHFS_METADATA_SIZE)
5810+
5811+#define SQUASHFS_FRAGMENT_INDEX_BYTES(A) (SQUASHFS_FRAGMENT_INDEXES(A) *\
5812+ sizeof(long long))
5813+
5814+/* inode lookup table defines */
5815+#define SQUASHFS_LOOKUP_BYTES(A) ((A) * sizeof(squashfs_inode_t))
5816+
5817+#define SQUASHFS_LOOKUP_BLOCK(A) (SQUASHFS_LOOKUP_BYTES(A) / \
5818+ SQUASHFS_METADATA_SIZE)
5819+
5820+#define SQUASHFS_LOOKUP_BLOCK_OFFSET(A) (SQUASHFS_LOOKUP_BYTES(A) % \
5821+ SQUASHFS_METADATA_SIZE)
5822+
5823+#define SQUASHFS_LOOKUP_BLOCKS(A) ((SQUASHFS_LOOKUP_BYTES(A) + \
5824+ SQUASHFS_METADATA_SIZE - 1) / \
5825+ SQUASHFS_METADATA_SIZE)
5826+
5827+#define SQUASHFS_LOOKUP_BLOCK_BYTES(A) (SQUASHFS_LOOKUP_BLOCKS(A) *\
5828+ sizeof(long long))
5829+
5830+/* uid lookup table defines */
5831+#define SQUASHFS_ID_BYTES(A) ((A) * sizeof(unsigned int))
5832+
5833+#define SQUASHFS_ID_BLOCK(A) (SQUASHFS_ID_BYTES(A) / \
5834+ SQUASHFS_METADATA_SIZE)
5835+
5836+#define SQUASHFS_ID_BLOCK_OFFSET(A) (SQUASHFS_ID_BYTES(A) % \
5837+ SQUASHFS_METADATA_SIZE)
5838+
5839+#define SQUASHFS_ID_BLOCKS(A) ((SQUASHFS_ID_BYTES(A) + \
5840+ SQUASHFS_METADATA_SIZE - 1) / \
5841+ SQUASHFS_METADATA_SIZE)
5842+
5843+#define SQUASHFS_ID_BLOCK_BYTES(A) (SQUASHFS_ID_BLOCKS(A) *\
5844+ sizeof(long long))
5845+
5846+/* cached data constants for filesystem */
5847+#define SQUASHFS_CACHED_BLKS 8
5848+
5849+#define SQUASHFS_MAX_FILE_SIZE_LOG 64
5850+
5851+#define SQUASHFS_MAX_FILE_SIZE ((long long) 1 << \
5852+ (SQUASHFS_MAX_FILE_SIZE_LOG - 2))
5853+
5854+#define SQUASHFS_MARKER_BYTE 0xff
5855+
5856+/* meta index cache */
5857+#define SQUASHFS_META_INDEXES (SQUASHFS_METADATA_SIZE / sizeof(unsigned int))
5858+#define SQUASHFS_META_ENTRIES 31
5859+#define SQUASHFS_META_NUMBER 8
5860+#define SQUASHFS_SLOTS 4
5861+
5862+struct meta_entry {
5863+ long long data_block;
5864+ unsigned int index_block;
5865+ unsigned short offset;
5866+ unsigned short pad;
5867+};
5868+
5869+struct meta_index {
5870+ unsigned int inode_number;
5871+ unsigned int offset;
5872+ unsigned short entries;
5873+ unsigned short skip;
5874+ unsigned short locked;
5875+ unsigned short pad;
5876+ struct meta_entry meta_entry[SQUASHFS_META_ENTRIES];
5877+};
5878+
5879+
5880+/*
5881+ * definitions for structures on disk
5882+ */
5883+
5884+typedef long long squashfs_block_t;
5885+typedef long long squashfs_inode_t;
5886+
5887+#define COMPRESSION_ZLIB 1
5888+
5889+struct squashfs_super_block {
5890+ unsigned int s_magic;
5891+ unsigned int inodes;
5892+ unsigned int mkfs_time /* time of filesystem creation */;
5893+ unsigned int block_size;
5894+ unsigned int fragments;
5895+ unsigned short compression;
5896+ unsigned short block_log;
5897+ unsigned short flags;
5898+ unsigned short no_ids;
5899+ unsigned short s_major;
5900+ unsigned short s_minor;
5901+ squashfs_inode_t root_inode;
5902+ long long bytes_used;
5903+ long long id_table_start;
5904+ long long xattr_table_start;
5905+ long long inode_table_start;
5906+ long long directory_table_start;
5907+ long long fragment_table_start;
5908+ long long lookup_table_start;
5909+};
5910+
5911+struct squashfs_dir_index {
5912+ unsigned int index;
5913+ unsigned int start_block;
5914+ unsigned int size;
5915+ unsigned char name[0];
5916+};
5917+
5918+#define SQUASHFS_BASE_INODE_HEADER \
5919+ unsigned short inode_type; \
5920+ unsigned short mode; \
5921+ unsigned short uid; \
5922+ unsigned short guid; \
5923+ unsigned int mtime; \
5924+ unsigned int inode_number;
5925+
5926+struct squashfs_base_inode_header {
5927+ SQUASHFS_BASE_INODE_HEADER;
5928+};
5929+
5930+struct squashfs_ipc_inode_header {
5931+ SQUASHFS_BASE_INODE_HEADER;
5932+ unsigned int nlink;
5933+};
5934+
5935+struct squashfs_dev_inode_header {
5936+ SQUASHFS_BASE_INODE_HEADER;
5937+ unsigned int nlink;
5938+ unsigned int rdev;
5939+};
5940+
5941+struct squashfs_symlink_inode_header {
5942+ SQUASHFS_BASE_INODE_HEADER;
5943+ unsigned int nlink;
5944+ unsigned int symlink_size;
5945+ char symlink[0];
5946+};
5947+
5948+struct squashfs_reg_inode_header {
5949+ SQUASHFS_BASE_INODE_HEADER;
5950+ unsigned int start_block;
5951+ unsigned int fragment;
5952+ unsigned int offset;
5953+ unsigned int file_size;
5954+ unsigned short block_list[0];
5955+};
5956+
5957+struct squashfs_lreg_inode_header {
5958+ SQUASHFS_BASE_INODE_HEADER;
5959+ squashfs_block_t start_block;
5960+ long long file_size;
5961+ long long sparse;
5962+ unsigned int nlink;
5963+ unsigned int fragment;
5964+ unsigned int offset;
5965+ unsigned int xattr;
5966+ unsigned short block_list[0];
5967+};
5968+
5969+struct squashfs_dir_inode_header {
5970+ SQUASHFS_BASE_INODE_HEADER;
5971+ unsigned int start_block;
5972+ unsigned int nlink;
5973+ unsigned short file_size;
5974+ unsigned short offset;
5975+ unsigned int parent_inode;
5976+};
5977+
5978+struct squashfs_ldir_inode_header {
5979+ SQUASHFS_BASE_INODE_HEADER;
5980+ unsigned int nlink;
5981+ unsigned int file_size;
5982+ unsigned int start_block;
5983+ unsigned int parent_inode;
5984+ unsigned short i_count;
5985+ unsigned short offset;
5986+ struct squashfs_dir_index index[0];
5987+};
5988+
5989+union squashfs_inode_header {
5990+ struct squashfs_base_inode_header base;
5991+ struct squashfs_dev_inode_header dev;
5992+ struct squashfs_symlink_inode_header symlink;
5993+ struct squashfs_reg_inode_header reg;
5994+ struct squashfs_lreg_inode_header lreg;
5995+ struct squashfs_dir_inode_header dir;
5996+ struct squashfs_ldir_inode_header ldir;
5997+ struct squashfs_ipc_inode_header ipc;
5998+};
5999+
6000+struct squashfs_dir_entry {
6001+ unsigned short offset;
6002+ short inode_number;
6003+ unsigned short type;
6004+ unsigned short size;
6005+ char name[0];
6006+};
6007+
6008+struct squashfs_dir_header {
6009+ unsigned int count;
6010+ unsigned int start_block;
6011+ unsigned int inode_number;
6012+};
6013+
6014+struct squashfs_fragment_entry {
6015+ long long start_block;
6016+ unsigned int size;
6017+ unsigned int unused;
6018+};
6019+
6020+extern int squashfs_uncompress_block(void *d, int dstlen, void *s, int srclen);
6021+extern int squashfs_uncompress_init(void);
6022+extern int squashfs_uncompress_exit(void);
6023+
6024+/*
6025+ * macros to convert each packed bitfield structure from little endian to big
6026+ * endian and vice versa. These are needed when creating or using a filesystem
6027+ * on a machine with different byte ordering to the target architecture.
6028+ *
6029+ */
6030+
6031+#define SQUASHFS_SWAP_START \
6032+ int bits;\
6033+ int b_pos;\
6034+ unsigned long long val;\
6035+ unsigned char *s;\
6036+ unsigned char *d;
6037+
6038+#define SQUASHFS_SWAP_SUPER_BLOCK(s, d) {\
6039+ SQUASHFS_SWAP_START\
6040+ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_super_block));\
6041+ SQUASHFS_SWAP((s)->s_magic, d, 0, 32);\
6042+ SQUASHFS_SWAP((s)->inodes, d, 32, 32);\
6043+ SQUASHFS_SWAP((s)->bytes_used_2, d, 64, 32);\
6044+ SQUASHFS_SWAP((s)->uid_start_2, d, 96, 32);\
6045+ SQUASHFS_SWAP((s)->guid_start_2, d, 128, 32);\
6046+ SQUASHFS_SWAP((s)->inode_table_start_2, d, 160, 32);\
6047+ SQUASHFS_SWAP((s)->directory_table_start_2, d, 192, 32);\
6048+ SQUASHFS_SWAP((s)->s_major, d, 224, 16);\
6049+ SQUASHFS_SWAP((s)->s_minor, d, 240, 16);\
6050+ SQUASHFS_SWAP((s)->block_size_1, d, 256, 16);\
6051+ SQUASHFS_SWAP((s)->block_log, d, 272, 16);\
6052+ SQUASHFS_SWAP((s)->flags, d, 288, 8);\
6053+ SQUASHFS_SWAP((s)->no_uids, d, 296, 8);\
6054+ SQUASHFS_SWAP((s)->no_guids, d, 304, 8);\
6055+ SQUASHFS_SWAP((s)->mkfs_time, d, 312, 32);\
6056+ SQUASHFS_SWAP((s)->root_inode, d, 344, 64);\
6057+ SQUASHFS_SWAP((s)->block_size, d, 408, 32);\
6058+ SQUASHFS_SWAP((s)->fragments, d, 440, 32);\
6059+ SQUASHFS_SWAP((s)->fragment_table_start_2, d, 472, 32);\
6060+ SQUASHFS_SWAP((s)->bytes_used, d, 504, 64);\
6061+ SQUASHFS_SWAP((s)->uid_start, d, 568, 64);\
6062+ SQUASHFS_SWAP((s)->guid_start, d, 632, 64);\
6063+ SQUASHFS_SWAP((s)->inode_table_start, d, 696, 64);\
6064+ SQUASHFS_SWAP((s)->directory_table_start, d, 760, 64);\
6065+ SQUASHFS_SWAP((s)->fragment_table_start, d, 824, 64);\
6066+ SQUASHFS_SWAP((s)->lookup_table_start, d, 888, 64);\
6067+}
6068+
6069+#define SQUASHFS_SWAP_BASE_INODE_CORE(s, d, n)\
6070+ SQUASHFS_MEMSET(s, d, n);\
6071+ SQUASHFS_SWAP((s)->inode_type, d, 0, 4);\
6072+ SQUASHFS_SWAP((s)->mode, d, 4, 12);\
6073+ SQUASHFS_SWAP((s)->uid, d, 16, 8);\
6074+ SQUASHFS_SWAP((s)->guid, d, 24, 8);\
6075+ SQUASHFS_SWAP((s)->mtime, d, 32, 32);\
6076+ SQUASHFS_SWAP((s)->inode_number, d, 64, 32);
6077+
6078+#define SQUASHFS_SWAP_BASE_INODE_HEADER(s, d, n) {\
6079+ SQUASHFS_SWAP_START\
6080+ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, n)\
6081+}
6082+
6083+#define SQUASHFS_SWAP_IPC_INODE_HEADER(s, d) {\
6084+ SQUASHFS_SWAP_START\
6085+ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
6086+ sizeof(struct squashfs_ipc_inode_header))\
6087+ SQUASHFS_SWAP((s)->nlink, d, 96, 32);\
6088+}
6089+
6090+#define SQUASHFS_SWAP_DEV_INODE_HEADER(s, d) {\
6091+ SQUASHFS_SWAP_START\
6092+ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
6093+ sizeof(struct squashfs_dev_inode_header)); \
6094+ SQUASHFS_SWAP((s)->nlink, d, 96, 32);\
6095+ SQUASHFS_SWAP((s)->rdev, d, 128, 16);\
6096+}
6097+
6098+#define SQUASHFS_SWAP_SYMLINK_INODE_HEADER(s, d) {\
6099+ SQUASHFS_SWAP_START\
6100+ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
6101+ sizeof(struct squashfs_symlink_inode_header));\
6102+ SQUASHFS_SWAP((s)->nlink, d, 96, 32);\
6103+ SQUASHFS_SWAP((s)->symlink_size, d, 128, 16);\
6104+}
6105+
6106+#define SQUASHFS_SWAP_REG_INODE_HEADER(s, d) {\
6107+ SQUASHFS_SWAP_START\
6108+ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
6109+ sizeof(struct squashfs_reg_inode_header));\
6110+ SQUASHFS_SWAP((s)->start_block, d, 96, 64);\
6111+ SQUASHFS_SWAP((s)->fragment, d, 160, 32);\
6112+ SQUASHFS_SWAP((s)->offset, d, 192, 32);\
6113+ SQUASHFS_SWAP((s)->file_size, d, 224, 32);\
6114+}
6115+
6116+#define SQUASHFS_SWAP_LREG_INODE_HEADER(s, d) {\
6117+ SQUASHFS_SWAP_START\
6118+ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
6119+ sizeof(struct squashfs_lreg_inode_header));\
6120+ SQUASHFS_SWAP((s)->nlink, d, 96, 32);\
6121+ SQUASHFS_SWAP((s)->start_block, d, 128, 64);\
6122+ SQUASHFS_SWAP((s)->fragment, d, 192, 32);\
6123+ SQUASHFS_SWAP((s)->offset, d, 224, 32);\
6124+ SQUASHFS_SWAP((s)->file_size, d, 256, 64);\
6125+}
6126+
6127+#define SQUASHFS_SWAP_DIR_INODE_HEADER(s, d) {\
6128+ SQUASHFS_SWAP_START\
6129+ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
6130+ sizeof(struct squashfs_dir_inode_header));\
6131+ SQUASHFS_SWAP((s)->nlink, d, 96, 32);\
6132+ SQUASHFS_SWAP((s)->file_size, d, 128, 19);\
6133+ SQUASHFS_SWAP((s)->offset, d, 147, 13);\
6134+ SQUASHFS_SWAP((s)->start_block, d, 160, 32);\
6135+ SQUASHFS_SWAP((s)->parent_inode, d, 192, 32);\
6136+}
6137+
6138+#define SQUASHFS_SWAP_LDIR_INODE_HEADER(s, d) {\
6139+ SQUASHFS_SWAP_START\
6140+ SQUASHFS_SWAP_BASE_INODE_CORE(s, d, \
6141+ sizeof(struct squashfs_ldir_inode_header));\
6142+ SQUASHFS_SWAP((s)->nlink, d, 96, 32);\
6143+ SQUASHFS_SWAP((s)->file_size, d, 128, 27);\
6144+ SQUASHFS_SWAP((s)->offset, d, 155, 13);\
6145+ SQUASHFS_SWAP((s)->start_block, d, 168, 32);\
6146+ SQUASHFS_SWAP((s)->i_count, d, 200, 16);\
6147+ SQUASHFS_SWAP((s)->parent_inode, d, 216, 32);\
6148+}
6149+
6150+#define SQUASHFS_SWAP_DIR_INDEX(s, d) {\
6151+ SQUASHFS_SWAP_START\
6152+ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_index));\
6153+ SQUASHFS_SWAP((s)->index, d, 0, 32);\
6154+ SQUASHFS_SWAP((s)->start_block, d, 32, 32);\
6155+ SQUASHFS_SWAP((s)->size, d, 64, 8);\
6156+}
6157+
6158+#define SQUASHFS_SWAP_DIR_HEADER(s, d) {\
6159+ SQUASHFS_SWAP_START\
6160+ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_header));\
6161+ SQUASHFS_SWAP((s)->count, d, 0, 8);\
6162+ SQUASHFS_SWAP((s)->start_block, d, 8, 32);\
6163+ SQUASHFS_SWAP((s)->inode_number, d, 40, 32);\
6164+}
6165+
6166+#define SQUASHFS_SWAP_DIR_ENTRY(s, d) {\
6167+ SQUASHFS_SWAP_START\
6168+ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_entry));\
6169+ SQUASHFS_SWAP((s)->offset, d, 0, 13);\
6170+ SQUASHFS_SWAP((s)->type, d, 13, 3);\
6171+ SQUASHFS_SWAP((s)->size, d, 16, 8);\
6172+ SQUASHFS_SWAP((s)->inode_number, d, 24, 16);\
6173+}
6174+
6175+#define SQUASHFS_SWAP_FRAGMENT_ENTRY(s, d) {\
6176+ SQUASHFS_SWAP_START\
6177+ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_fragment_entry));\
6178+ SQUASHFS_SWAP((s)->start_block, d, 0, 64);\
6179+ SQUASHFS_SWAP((s)->size, d, 64, 32);\
6180+}
6181+
6182+#define SQUASHFS_SWAP_INODE_T(s, d) SQUASHFS_SWAP_LONG_LONGS(s, d, 1)
6183+
6184+#define SQUASHFS_SWAP_SHORTS(s, d, n) {\
6185+ int entry;\
6186+ int bit_position;\
6187+ SQUASHFS_SWAP_START\
6188+ SQUASHFS_MEMSET(s, d, n * 2);\
6189+ for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \
6190+ 16)\
6191+ SQUASHFS_SWAP(s[entry], d, bit_position, 16);\
6192+}
6193+
6194+#define SQUASHFS_SWAP_INTS(s, d, n) {\
6195+ int entry;\
6196+ int bit_position;\
6197+ SQUASHFS_SWAP_START\
6198+ SQUASHFS_MEMSET(s, d, n * 4);\
6199+ for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \
6200+ 32)\
6201+ SQUASHFS_SWAP(s[entry], d, bit_position, 32);\
6202+}
6203+
6204+#define SQUASHFS_SWAP_LONG_LONGS(s, d, n) {\
6205+ int entry;\
6206+ int bit_position;\
6207+ SQUASHFS_SWAP_START\
6208+ SQUASHFS_MEMSET(s, d, n * 8);\
6209+ for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \
6210+ 64)\
6211+ SQUASHFS_SWAP(s[entry], d, bit_position, 64);\
6212+}
6213+
6214+#define SQUASHFS_SWAP_DATA(s, d, n, bits) {\
6215+ int entry;\
6216+ int bit_position;\
6217+ SQUASHFS_SWAP_START\
6218+ SQUASHFS_MEMSET(s, d, n * bits / 8);\
6219+ for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += \
6220+ bits)\
6221+ SQUASHFS_SWAP(s[entry], d, bit_position, bits);\
6222+}
6223+
6224+#define SQUASHFS_SWAP_FRAGMENT_INDEXES(s, d, n) SQUASHFS_SWAP_LONG_LONGS(s, d, n)
6225+#define SQUASHFS_SWAP_LOOKUP_BLOCKS(s, d, n) SQUASHFS_SWAP_LONG_LONGS(s, d, n)
6226+#define SQUASHFS_SWAP_ID_BLOCKS(s, d, n) SQUASHFS_SWAP_LONG_LONGS(s, d, n)
6227+
6228+#ifdef CONFIG_SQUASHFS_1_0_COMPATIBILITY
6229+
6230+struct squashfs_base_inode_header_1 {
6231+ unsigned int inode_type:4;
6232+ unsigned int mode:12; /* protection */
6233+ unsigned int uid:4; /* index into uid table */
6234+ unsigned int guid:4; /* index into guid table */
6235+} __attribute__ ((packed));
6236+
6237+struct squashfs_ipc_inode_header_1 {
6238+ unsigned int inode_type:4;
6239+ unsigned int mode:12; /* protection */
6240+ unsigned int uid:4; /* index into uid table */
6241+ unsigned int guid:4; /* index into guid table */
6242+ unsigned int type:4;
6243+ unsigned int offset:4;
6244+} __attribute__ ((packed));
6245+
6246+struct squashfs_dev_inode_header_1 {
6247+ unsigned int inode_type:4;
6248+ unsigned int mode:12; /* protection */
6249+ unsigned int uid:4; /* index into uid table */
6250+ unsigned int guid:4; /* index into guid table */
6251+ unsigned short rdev;
6252+} __attribute__ ((packed));
6253+
6254+struct squashfs_symlink_inode_header_1 {
6255+ unsigned int inode_type:4;
6256+ unsigned int mode:12; /* protection */
6257+ unsigned int uid:4; /* index into uid table */
6258+ unsigned int guid:4; /* index into guid table */
6259+ unsigned short symlink_size;
6260+ char symlink[0];
6261+} __attribute__ ((packed));
6262+
6263+struct squashfs_reg_inode_header_1 {
6264+ unsigned int inode_type:4;
6265+ unsigned int mode:12; /* protection */
6266+ unsigned int uid:4; /* index into uid table */
6267+ unsigned int guid:4; /* index into guid table */
6268+ unsigned int mtime;
6269+ unsigned int start_block;
6270+ unsigned int file_size:32;
6271+ unsigned short block_list[0];
6272+} __attribute__ ((packed));
6273+
6274+struct squashfs_dir_inode_header_1 {
6275+ unsigned int inode_type:4;
6276+ unsigned int mode:12; /* protection */
6277+ unsigned int uid:4; /* index into uid table */
6278+ unsigned int guid:4; /* index into guid table */
6279+ unsigned int file_size:19;
6280+ unsigned int offset:13;
6281+ unsigned int mtime;
6282+ unsigned int start_block:24;
6283+} __attribute__ ((packed));
6284+
6285+union squashfs_inode_header_1 {
6286+ struct squashfs_base_inode_header_1 base;
6287+ struct squashfs_dev_inode_header_1 dev;
6288+ struct squashfs_symlink_inode_header_1 symlink;
6289+ struct squashfs_reg_inode_header_1 reg;
6290+ struct squashfs_dir_inode_header_1 dir;
6291+ struct squashfs_ipc_inode_header_1 ipc;
6292+};
6293+
6294+#define SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, n) \
6295+ SQUASHFS_MEMSET(s, d, n);\
6296+ SQUASHFS_SWAP((s)->inode_type, d, 0, 4);\
6297+ SQUASHFS_SWAP((s)->mode, d, 4, 12);\
6298+ SQUASHFS_SWAP((s)->uid, d, 16, 4);\
6299+ SQUASHFS_SWAP((s)->guid, d, 20, 4);
6300+
6301+#define SQUASHFS_SWAP_BASE_INODE_HEADER_1(s, d, n) {\
6302+ SQUASHFS_SWAP_START\
6303+ SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, n)\
6304+}
6305+
6306+#define SQUASHFS_SWAP_IPC_INODE_HEADER_1(s, d) {\
6307+ SQUASHFS_SWAP_START\
6308+ SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \
6309+ sizeof(struct squashfs_ipc_inode_header_1));\
6310+ SQUASHFS_SWAP((s)->type, d, 24, 4);\
6311+ SQUASHFS_SWAP((s)->offset, d, 28, 4);\
6312+}
6313+
6314+#define SQUASHFS_SWAP_DEV_INODE_HEADER_1(s, d) {\
6315+ SQUASHFS_SWAP_START\
6316+ SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \
6317+ sizeof(struct squashfs_dev_inode_header_1));\
6318+ SQUASHFS_SWAP((s)->rdev, d, 24, 16);\
6319+}
6320+
6321+#define SQUASHFS_SWAP_SYMLINK_INODE_HEADER_1(s, d) {\
6322+ SQUASHFS_SWAP_START\
6323+ SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \
6324+ sizeof(struct squashfs_symlink_inode_header_1));\
6325+ SQUASHFS_SWAP((s)->symlink_size, d, 24, 16);\
6326+}
6327+
6328+#define SQUASHFS_SWAP_REG_INODE_HEADER_1(s, d) {\
6329+ SQUASHFS_SWAP_START\
6330+ SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \
6331+ sizeof(struct squashfs_reg_inode_header_1));\
6332+ SQUASHFS_SWAP((s)->mtime, d, 24, 32);\
6333+ SQUASHFS_SWAP((s)->start_block, d, 56, 32);\
6334+ SQUASHFS_SWAP((s)->file_size, d, 88, 32);\
6335+}
6336+
6337+#define SQUASHFS_SWAP_DIR_INODE_HEADER_1(s, d) {\
6338+ SQUASHFS_SWAP_START\
6339+ SQUASHFS_SWAP_BASE_INODE_CORE_1(s, d, \
6340+ sizeof(struct squashfs_dir_inode_header_1));\
6341+ SQUASHFS_SWAP((s)->file_size, d, 24, 19);\
6342+ SQUASHFS_SWAP((s)->offset, d, 43, 13);\
6343+ SQUASHFS_SWAP((s)->mtime, d, 56, 32);\
6344+ SQUASHFS_SWAP((s)->start_block, d, 88, 24);\
6345+}
6346+
6347+#endif
6348+
6349+#ifdef CONFIG_SQUASHFS_2_0_COMPATIBILITY
6350+
6351+struct squashfs_dir_index_2 {
6352+ unsigned int index:27;
6353+ unsigned int start_block:29;
6354+ unsigned char size;
6355+ unsigned char name[0];
6356+} __attribute__ ((packed));
6357+
6358+struct squashfs_base_inode_header_2 {
6359+ unsigned int inode_type:4;
6360+ unsigned int mode:12; /* protection */
6361+ unsigned int uid:8; /* index into uid table */
6362+ unsigned int guid:8; /* index into guid table */
6363+} __attribute__ ((packed));
6364+
6365+struct squashfs_ipc_inode_header_2 {
6366+ unsigned int inode_type:4;
6367+ unsigned int mode:12; /* protection */
6368+ unsigned int uid:8; /* index into uid table */
6369+ unsigned int guid:8; /* index into guid table */
6370+} __attribute__ ((packed));
6371+
6372+struct squashfs_dev_inode_header_2 {
6373+ unsigned int inode_type:4;
6374+ unsigned int mode:12; /* protection */
6375+ unsigned int uid:8; /* index into uid table */
6376+ unsigned int guid:8; /* index into guid table */
6377+ unsigned short rdev;
6378+} __attribute__ ((packed));
6379+
6380+struct squashfs_symlink_inode_header_2 {
6381+ unsigned int inode_type:4;
6382+ unsigned int mode:12; /* protection */
6383+ unsigned int uid:8; /* index into uid table */
6384+ unsigned int guid:8; /* index into guid table */
6385+ unsigned short symlink_size;
6386+ char symlink[0];
6387+} __attribute__ ((packed));
6388+
6389+struct squashfs_reg_inode_header_2 {
6390+ unsigned int inode_type:4;
6391+ unsigned int mode:12; /* protection */
6392+ unsigned int uid:8; /* index into uid table */
6393+ unsigned int guid:8; /* index into guid table */
6394+ unsigned int mtime;
6395+ unsigned int start_block;
6396+ unsigned int fragment;
6397+ unsigned int offset;
6398+ unsigned int file_size:32;
6399+ unsigned short block_list[0];
6400+} __attribute__ ((packed));
6401+
6402+struct squashfs_dir_inode_header_2 {
6403+ unsigned int inode_type:4;
6404+ unsigned int mode:12; /* protection */
6405+ unsigned int uid:8; /* index into uid table */
6406+ unsigned int guid:8; /* index into guid table */
6407+ unsigned int file_size:19;
6408+ unsigned int offset:13;
6409+ unsigned int mtime;
6410+ unsigned int start_block:24;
6411+} __attribute__ ((packed));
6412+
6413+struct squashfs_ldir_inode_header_2 {
6414+ unsigned int inode_type:4;
6415+ unsigned int mode:12; /* protection */
6416+ unsigned int uid:8; /* index into uid table */
6417+ unsigned int guid:8; /* index into guid table */
6418+ unsigned int file_size:27;
6419+ unsigned int offset:13;
6420+ unsigned int mtime;
6421+ unsigned int start_block:24;
6422+ unsigned int i_count:16;
6423+ struct squashfs_dir_index_2 index[0];
6424+} __attribute__ ((packed));
6425+
6426+union squashfs_inode_header_2 {
6427+ struct squashfs_base_inode_header_2 base;
6428+ struct squashfs_dev_inode_header_2 dev;
6429+ struct squashfs_symlink_inode_header_2 symlink;
6430+ struct squashfs_reg_inode_header_2 reg;
6431+ struct squashfs_dir_inode_header_2 dir;
6432+ struct squashfs_ldir_inode_header_2 ldir;
6433+ struct squashfs_ipc_inode_header_2 ipc;
6434+};
6435+
6436+struct squashfs_dir_header_2 {
6437+ unsigned int count:8;
6438+ unsigned int start_block:24;
6439+} __attribute__ ((packed));
6440+
6441+struct squashfs_dir_entry_2 {
6442+ unsigned int offset:13;
6443+ unsigned int type:3;
6444+ unsigned int size:8;
6445+ char name[0];
6446+} __attribute__ ((packed));
6447+
6448+struct squashfs_fragment_entry_2 {
6449+ unsigned int start_block;
6450+ unsigned int size;
6451+} __attribute__ ((packed));
6452+
6453+#define SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, n)\
6454+ SQUASHFS_MEMSET(s, d, n);\
6455+ SQUASHFS_SWAP((s)->inode_type, d, 0, 4);\
6456+ SQUASHFS_SWAP((s)->mode, d, 4, 12);\
6457+ SQUASHFS_SWAP((s)->uid, d, 16, 8);\
6458+ SQUASHFS_SWAP((s)->guid, d, 24, 8);\
6459+
6460+#define SQUASHFS_SWAP_BASE_INODE_HEADER_2(s, d, n) {\
6461+ SQUASHFS_SWAP_START\
6462+ SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, n)\
6463+}
6464+
6465+#define SQUASHFS_SWAP_IPC_INODE_HEADER_2(s, d) \
6466+ SQUASHFS_SWAP_BASE_INODE_HEADER_2(s, d, sizeof(struct squashfs_ipc_inode_header_2))
6467+
6468+#define SQUASHFS_SWAP_DEV_INODE_HEADER_2(s, d) {\
6469+ SQUASHFS_SWAP_START\
6470+ SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \
6471+ sizeof(struct squashfs_dev_inode_header_2)); \
6472+ SQUASHFS_SWAP((s)->rdev, d, 32, 16);\
6473+}
6474+
6475+#define SQUASHFS_SWAP_SYMLINK_INODE_HEADER_2(s, d) {\
6476+ SQUASHFS_SWAP_START\
6477+ SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \
6478+ sizeof(struct squashfs_symlink_inode_header_2));\
6479+ SQUASHFS_SWAP((s)->symlink_size, d, 32, 16);\
6480+}
6481+
6482+#define SQUASHFS_SWAP_REG_INODE_HEADER_2(s, d) {\
6483+ SQUASHFS_SWAP_START\
6484+ SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \
6485+ sizeof(struct squashfs_reg_inode_header_2));\
6486+ SQUASHFS_SWAP((s)->mtime, d, 32, 32);\
6487+ SQUASHFS_SWAP((s)->start_block, d, 64, 32);\
6488+ SQUASHFS_SWAP((s)->fragment, d, 96, 32);\
6489+ SQUASHFS_SWAP((s)->offset, d, 128, 32);\
6490+ SQUASHFS_SWAP((s)->file_size, d, 160, 32);\
6491+}
6492+
6493+#define SQUASHFS_SWAP_DIR_INODE_HEADER_2(s, d) {\
6494+ SQUASHFS_SWAP_START\
6495+ SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \
6496+ sizeof(struct squashfs_dir_inode_header_2));\
6497+ SQUASHFS_SWAP((s)->file_size, d, 32, 19);\
6498+ SQUASHFS_SWAP((s)->offset, d, 51, 13);\
6499+ SQUASHFS_SWAP((s)->mtime, d, 64, 32);\
6500+ SQUASHFS_SWAP((s)->start_block, d, 96, 24);\
6501+}
6502+
6503+#define SQUASHFS_SWAP_LDIR_INODE_HEADER_2(s, d) {\
6504+ SQUASHFS_SWAP_START\
6505+ SQUASHFS_SWAP_BASE_INODE_CORE_2(s, d, \
6506+ sizeof(struct squashfs_ldir_inode_header_2));\
6507+ SQUASHFS_SWAP((s)->file_size, d, 32, 27);\
6508+ SQUASHFS_SWAP((s)->offset, d, 59, 13);\
6509+ SQUASHFS_SWAP((s)->mtime, d, 72, 32);\
6510+ SQUASHFS_SWAP((s)->start_block, d, 104, 24);\
6511+ SQUASHFS_SWAP((s)->i_count, d, 128, 16);\
6512+}
6513+
6514+#define SQUASHFS_SWAP_DIR_INDEX_2(s, d) {\
6515+ SQUASHFS_SWAP_START\
6516+ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_index_2));\
6517+ SQUASHFS_SWAP((s)->index, d, 0, 27);\
6518+ SQUASHFS_SWAP((s)->start_block, d, 27, 29);\
6519+ SQUASHFS_SWAP((s)->size, d, 56, 8);\
6520+}
6521+#define SQUASHFS_SWAP_DIR_HEADER_2(s, d) {\
6522+ SQUASHFS_SWAP_START\
6523+ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_header_2));\
6524+ SQUASHFS_SWAP((s)->count, d, 0, 8);\
6525+ SQUASHFS_SWAP((s)->start_block, d, 8, 24);\
6526+}
6527+
6528+#define SQUASHFS_SWAP_DIR_ENTRY_2(s, d) {\
6529+ SQUASHFS_SWAP_START\
6530+ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_dir_entry_2));\
6531+ SQUASHFS_SWAP((s)->offset, d, 0, 13);\
6532+ SQUASHFS_SWAP((s)->type, d, 13, 3);\
6533+ SQUASHFS_SWAP((s)->size, d, 16, 8);\
6534+}
6535+
6536+#define SQUASHFS_SWAP_FRAGMENT_ENTRY_2(s, d) {\
6537+ SQUASHFS_SWAP_START\
6538+ SQUASHFS_MEMSET(s, d, sizeof(struct squashfs_fragment_entry_2));\
6539+ SQUASHFS_SWAP((s)->start_block, d, 0, 32);\
6540+ SQUASHFS_SWAP((s)->size, d, 32, 32);\
6541+}
6542+
6543+#define SQUASHFS_SWAP_FRAGMENT_INDEXES_2(s, d, n) SQUASHFS_SWAP_INTS(s, d, n)
6544+
6545+/* fragment and fragment table defines */
6546+#define SQUASHFS_FRAGMENT_BYTES_2(A) (A * sizeof(struct squashfs_fragment_entry_2))
6547+
6548+#define SQUASHFS_FRAGMENT_INDEX_2(A) (SQUASHFS_FRAGMENT_BYTES_2(A) / \
6549+ SQUASHFS_METADATA_SIZE)
6550+
6551+#define SQUASHFS_FRAGMENT_INDEX_OFFSET_2(A) (SQUASHFS_FRAGMENT_BYTES_2(A) % \
6552+ SQUASHFS_METADATA_SIZE)
6553+
6554+#define SQUASHFS_FRAGMENT_INDEXES_2(A) ((SQUASHFS_FRAGMENT_BYTES_2(A) + \
6555+ SQUASHFS_METADATA_SIZE - 1) / \
6556+ SQUASHFS_METADATA_SIZE)
6557+
6558+#define SQUASHFS_FRAGMENT_INDEX_BYTES_2(A) (SQUASHFS_FRAGMENT_INDEXES_2(A) *\
6559+ sizeof(int))
6560+
6561+#endif
6562+
6563+#ifdef __KERNEL__
6564+
6565+/*
6566+ * macros used to swap each structure entry, taking into account
6567+ * bitfields and different bitfield placing conventions on differing
6568+ * architectures
6569+ */
6570+
6571+#include <asm/byteorder.h>
6572+
6573+#ifdef __BIG_ENDIAN
6574+ /* convert from little endian to big endian */
6575+#define SQUASHFS_SWAP(value, p, pos, tbits) _SQUASHFS_SWAP(value, p, pos, \
6576+ tbits, b_pos)
6577+#else
6578+ /* convert from big endian to little endian */
6579+#define SQUASHFS_SWAP(value, p, pos, tbits) _SQUASHFS_SWAP(value, p, pos, \
6580+ tbits, 64 - tbits - b_pos)
6581+#endif
6582+
6583+#define _SQUASHFS_SWAP(value, p, pos, tbits, SHIFT) {\
6584+ b_pos = pos % 8;\
6585+ val = 0;\
6586+ s = (unsigned char *)p + (pos / 8);\
6587+ d = ((unsigned char *) &val) + 7;\
6588+ for(bits = 0; bits < (tbits + b_pos); bits += 8) \
6589+ *d-- = *s++;\
6590+ value = (val >> (SHIFT))/* & ((1 << tbits) - 1)*/;\
6591+}
6592+
6593+#define SQUASHFS_MEMSET(s, d, n) memset(s, 0, n);
6594+
6595+#endif
6596+#endif
6597diff -uNr a/include/linux/squashfs_fs_i.h b/include/linux/squashfs_fs_i.h
6598--- a/include/linux/squashfs_fs_i.h 1969-12-31 16:00:00.000000000 -0800
6599+++ b/include/linux/squashfs_fs_i.h 2008-08-13 16:16:05.000000000 -0700
6600@@ -0,0 +1,45 @@
6601+#ifndef SQUASHFS_FS_I
6602+#define SQUASHFS_FS_I
6603+/*
6604+ * Squashfs
6605+ *
6606+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
6607+ * Phillip Lougher <phillip@lougher.demon.co.uk>
6608+ *
6609+ * This program is free software; you can redistribute it and/or
6610+ * modify it under the terms of the GNU General Public License
6611+ * as published by the Free Software Foundation; either version 2,
6612+ * or (at your option) any later version.
6613+ *
6614+ * This program is distributed in the hope that it will be useful,
6615+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6616+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6617+ * GNU General Public License for more details.
6618+ *
6619+ * You should have received a copy of the GNU General Public License
6620+ * along with this program; if not, write to the Free Software
6621+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
6622+ *
6623+ * squashfs_fs_i.h
6624+ */
6625+
6626+struct squashfs_inode_info {
6627+ long long start_block;
6628+ unsigned int offset;
6629+ union {
6630+ struct {
6631+ long long fragment_start_block;
6632+ unsigned int fragment_size;
6633+ unsigned int fragment_offset;
6634+ long long block_list_start;
6635+ } s1;
6636+ struct {
6637+ long long directory_index_start;
6638+ unsigned int directory_index_offset;
6639+ unsigned int directory_index_count;
6640+ unsigned int parent_inode;
6641+ } s2;
6642+ } u;
6643+ struct inode vfs_inode;
6644+};
6645+#endif
6646diff -uNr a/include/linux/squashfs_fs_sb.h b/include/linux/squashfs_fs_sb.h
6647--- a/include/linux/squashfs_fs_sb.h 1969-12-31 16:00:00.000000000 -0800
6648+++ b/include/linux/squashfs_fs_sb.h 2008-08-13 16:16:05.000000000 -0700
6649@@ -0,0 +1,78 @@
6650+#ifndef SQUASHFS_FS_SB
6651+#define SQUASHFS_FS_SB
6652+/*
6653+ * Squashfs
6654+ *
6655+ * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008
6656+ * Phillip Lougher <phillip@lougher.demon.co.uk>
6657+ *
6658+ * This program is free software; you can redistribute it and/or
6659+ * modify it under the terms of the GNU General Public License
6660+ * as published by the Free Software Foundation; either version 2,
6661+ * or (at your option) any later version.
6662+ *
6663+ * This program is distributed in the hope that it will be useful,
6664+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
6665+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6666+ * GNU General Public License for more details.
6667+ *
6668+ * You should have received a copy of the GNU General Public License
6669+ * along with this program; if not, write to the Free Software
6670+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
6671+ *
6672+ * squashfs_fs_sb.h
6673+ */
6674+
6675+#include <linux/squashfs_fs.h>
6676+
6677+struct squashfs_cache_entry {
6678+ long long block;
6679+ int length;
6680+ int locked;
6681+ long long next_index;
6682+ char pending;
6683+ char error;
6684+ int waiting;
6685+ wait_queue_head_t wait_queue;
6686+ char *data;
6687+};
6688+
6689+struct squashfs_cache {
6690+ char *name;
6691+ int entries;
6692+ int block_size;
6693+ int next_blk;
6694+ int waiting;
6695+ int unused_blks;
6696+ int use_vmalloc;
6697+ spinlock_t lock;
6698+ wait_queue_head_t wait_queue;
6699+ struct squashfs_cache_entry entry[0];
6700+};
6701+
6702+struct squashfs_sb_info {
6703+ struct squashfs_super_block sblk;
6704+ int devblksize;
6705+ int devblksize_log2;
6706+ int swap;
6707+ struct squashfs_cache *block_cache;
6708+ struct squashfs_cache *fragment_cache;
6709+ int next_meta_index;
6710+ unsigned int *id_table;
6711+ long long *fragment_index;
6712+ unsigned int *fragment_index_2;
6713+ char *read_page;
6714+ struct mutex read_data_mutex;
6715+ struct mutex read_page_mutex;
6716+ struct mutex meta_index_mutex;
6717+ struct meta_index *meta_index;
6718+ z_stream stream;
6719+ long long *inode_lookup_table;
6720+ int (*read_inode)(struct inode *i, squashfs_inode_t \
6721+ inode);
6722+ long long (*read_blocklist)(struct inode *inode, int \
6723+ index, int readahead_blks, char *block_list, \
6724+ unsigned short **block_p, unsigned int *bsize);
6725+ int (*read_fragment_index_table)(struct super_block *s);
6726+};
6727+#endif
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27-rc1/0010_unionfs-2.4_for_2.6.27-rc1.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc1/0010_unionfs-2.4_for_2.6.27-rc1.patch
new file mode 100644
index 0000000000..8a2e83aa6c
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc1/0010_unionfs-2.4_for_2.6.27-rc1.patch
@@ -0,0 +1,11320 @@
1diff --git a/Documentation/filesystems/00-INDEX b/Documentation/filesystems/00-INDEX
2index 52cd611..bc6b437 100644
3--- a/Documentation/filesystems/00-INDEX
4+++ b/Documentation/filesystems/00-INDEX
5@@ -106,6 +106,8 @@ udf.txt
6 - info and mount options for the UDF filesystem.
7 ufs.txt
8 - info on the ufs filesystem.
9+unionfs/
10+ - info on the unionfs filesystem
11 vfat.txt
12 - info on using the VFAT filesystem used in Windows NT and Windows 95
13 vfs.txt
14diff --git a/Documentation/filesystems/unionfs/00-INDEX b/Documentation/filesystems/unionfs/00-INDEX
15new file mode 100644
16index 0000000..96fdf67
17--- /dev/null
18+++ b/Documentation/filesystems/unionfs/00-INDEX
19@@ -0,0 +1,10 @@
20+00-INDEX
21+ - this file.
22+concepts.txt
23+ - A brief introduction of concepts.
24+issues.txt
25+ - A summary of known issues with unionfs.
26+rename.txt
27+ - Information regarding rename operations.
28+usage.txt
29+ - Usage information and examples.
30diff --git a/Documentation/filesystems/unionfs/concepts.txt b/Documentation/filesystems/unionfs/concepts.txt
31new file mode 100644
32index 0000000..b853788
33--- /dev/null
34+++ b/Documentation/filesystems/unionfs/concepts.txt
35@@ -0,0 +1,287 @@
36+Unionfs 2.x CONCEPTS:
37+=====================
38+
39+This file describes the concepts needed by a namespace unification file
40+system.
41+
42+
43+Branch Priority:
44+================
45+
46+Each branch is assigned a unique priority - starting from 0 (highest
47+priority). No two branches can have the same priority.
48+
49+
50+Branch Mode:
51+============
52+
53+Each branch is assigned a mode - read-write or read-only. This allows
54+directories on media mounted read-write to be used in a read-only manner.
55+
56+
57+Whiteouts:
58+==========
59+
60+A whiteout removes a file name from the namespace. Whiteouts are needed when
61+one attempts to remove a file on a read-only branch.
62+
63+Suppose we have a two-branch union, where branch 0 is read-write and branch
64+1 is read-only. And a file 'foo' on branch 1:
65+
66+./b0/
67+./b1/
68+./b1/foo
69+
70+The unified view would simply be:
71+
72+./union/
73+./union/foo
74+
75+Since 'foo' is stored on a read-only branch, it cannot be removed. A
76+whiteout is used to remove the name 'foo' from the unified namespace. Again,
77+since branch 1 is read-only, the whiteout cannot be created there. So, we
78+try on a higher priority (lower numerically) branch and create the whiteout
79+there.
80+
81+./b0/
82+./b0/.wh.foo
83+./b1/
84+./b1/foo
85+
86+Later, when Unionfs traverses branches (due to lookup or readdir), it
87+eliminate 'foo' from the namespace (as well as the whiteout itself.)
88+
89+
90+Opaque Directories:
91+===================
92+
93+Assume we have a unionfs mount comprising of two branches. Branch 0 is
94+empty; branch 1 has the directory /a and file /a/f. Let's say we mount a
95+union of branch 0 as read-write and branch 1 as read-only. Now, let's say
96+we try to perform the following operation in the union:
97+
98+ rm -fr a
99+
100+Because branch 1 is not writable, we cannot physically remove the file /a/f
101+or the directory /a. So instead, we will create a whiteout in branch 0
102+named /.wh.a, masking out the name "a" from branch 1. Next, let's say we
103+try to create a directory named "a" as follows:
104+
105+ mkdir a
106+
107+Because we have a whiteout for "a" already, Unionfs behaves as if "a"
108+doesn't exist, and thus will delete the whiteout and replace it with an
109+actual directory named "a".
110+
111+The problem now is that if you try to "ls" in the union, Unionfs will
112+perform is normal directory name unification, for *all* directories named
113+"a" in all branches. This will cause the file /a/f from branch 1 to
114+re-appear in the union's namespace, which violates Unix semantics.
115+
116+To avoid this problem, we have a different form of whiteouts for
117+directories, called "opaque directories" (same as BSD Union Mount does).
118+Whenever we replace a whiteout with a directory, that directory is marked as
119+opaque. In Unionfs 2.x, it means that we create a file named
120+/a/.wh.__dir_opaque in branch 0, after having created directory /a there.
121+When unionfs notices that a directory is opaque, it stops all namespace
122+operations (including merging readdir contents) at that opaque directory.
123+This prevents re-exposing names from masked out directories.
124+
125+
126+Duplicate Elimination:
127+======================
128+
129+It is possible for files on different branches to have the same name.
130+Unionfs then has to select which instance of the file to show to the user.
131+Given the fact that each branch has a priority associated with it, the
132+simplest solution is to take the instance from the highest priority
133+(numerically lowest value) and "hide" the others.
134+
135+
136+Unlinking:
137+=========
138+
139+Unlink operation on non-directory instances is optimized to remove the
140+maximum possible objects in case multiple underlying branches have the same
141+file name. The unlink operation will first try to delete file instances
142+from highest priority branch and then move further to delete from remaining
143+branches in order of their decreasing priority. Consider a case (F..D..F),
144+where F is a file and D is a directory of the same name; here, some
145+intermediate branch could have an empty directory instance with the same
146+name, so this operation also tries to delete this directory instance and
147+proceed further to delete from next possible lower priority branch. The
148+unionfs unlink operation will smoothly delete the files with same name from
149+all possible underlying branches. In case if some error occurs, it creates
150+whiteout in highest priority branch that will hide file instance in rest of
151+the branches. An error could occur either if an unlink operations in any of
152+the underlying branch failed or if a branch has no write permission.
153+
154+This unlinking policy is known as "delete all" and it has the benefit of
155+overall reducing the number of inodes used by duplicate files, and further
156+reducing the total number of inodes consumed by whiteouts. The cost is of
157+extra processing, but testing shows this extra processing is well worth the
158+savings.
159+
160+
161+Copyup:
162+=======
163+
164+When a change is made to the contents of a file's data or meta-data, they
165+have to be stored somewhere. The best way is to create a copy of the
166+original file on a branch that is writable, and then redirect the write
167+though to this copy. The copy must be made on a higher priority branch so
168+that lookup and readdir return this newer "version" of the file rather than
169+the original (see duplicate elimination).
170+
171+An entire unionfs mount can be read-only or read-write. If it's read-only,
172+then none of the branches will be written to, even if some of the branches
173+are physically writeable. If the unionfs mount is read-write, then the
174+leftmost (highest priority) branch must be writeable (for copyup to take
175+place); the remaining branches can be any mix of read-write and read-only.
176+
177+In a writeable mount, unionfs will create new files/dir in the leftmost
178+branch. If one tries to modify a file in a read-only branch/media, unionfs
179+will copyup the file to the leftmost branch and modify it there. If you try
180+to modify a file from a writeable branch which is not the leftmost branch,
181+then unionfs will modify it in that branch; this is useful if you, say,
182+unify differnet packages (e.g., apache, sendmail, ftpd, etc.) and you want
183+changes to specific package files to remain logically in the directory where
184+they came from.
185+
186+Cache Coherency:
187+================
188+
189+Unionfs users often want to be able to modify files and directories directly
190+on the lower branches, and have those changes be visible at the Unionfs
191+level. This means that data (e.g., pages) and meta-data (dentries, inodes,
192+open files, etc.) have to be synchronized between the upper and lower
193+layers. In other words, the newest changes from a layer below have to be
194+propagated to the Unionfs layer above. If the two layers are not in sync, a
195+cache incoherency ensues, which could lead to application failures and even
196+oopses. The Linux kernel, however, has a rather limited set of mechanisms
197+to ensure this inter-layer cache coherency---so Unionfs has to do most of
198+the hard work on its own.
199+
200+Maintaining Invariants:
201+
202+The way Unionfs ensures cache coherency is as follows. At each entry point
203+to a Unionfs file system method, we call a utility function to validate the
204+primary objects of this method. Generally, we call unionfs_file_revalidate
205+on open files, and __unionfs_d_revalidate_chain on dentries (which also
206+validates inodes). These utility functions check to see whether the upper
207+Unionfs object is in sync with any of the lower objects that it represents.
208+The checks we perform include whether the Unionfs superblock has a newer
209+generation number, or if any of the lower objects mtime's or ctime's are
210+newer. (Note: generation numbers change when branch-management commands are
211+issued, so in a way, maintaining cache coherency is also very important for
212+branch-management.) If indeed we determine that any Unionfs object is no
213+longer in sync with its lower counterparts, then we rebuild that object
214+similarly to how we do so for branch-management.
215+
216+While rebuilding Unionfs's objects, we also purge any page mappings and
217+truncate inode pages (see fs/unionfs/dentry.c:purge_inode_data). This is to
218+ensure that Unionfs will re-get the newer data from the lower branches. We
219+perform this purging only if the Unionfs operation in question is a reading
220+operation; if Unionfs is performing a data writing operation (e.g., ->write,
221+->commit_write, etc.) then we do NOT flush the lower mappings/pages: this is
222+because (1) a self-deadlock could occur and (2) the upper Unionfs pages are
223+considered more authoritative anyway, as they are newer and will overwrite
224+any lower pages.
225+
226+Unionfs maintains the following important invariant regarding mtime's,
227+ctime's, and atime's: the upper inode object's times are the max() of all of
228+the lower ones. For non-directory objects, there's only one object below,
229+so the mapping is simple; for directory objects, there could me multiple
230+lower objects and we have to sync up with the newest one of all the lower
231+ones. This invariant is important to maintain, especially for directories
232+(besides, we need this to be POSIX compliant). A union could comprise
233+multiple writable branches, each of which could change. If we don't reflect
234+the newest possible mtime/ctime, some applications could fail. For example,
235+NFSv2/v3 exports check for newer directory mtimes on the server to determine
236+if the client-side attribute cache should be purged.
237+
238+To maintain these important invariants, of course, Unionfs carefully
239+synchronizes upper and lower times in various places. For example, if we
240+copy-up a file to a top-level branch, the parent directory where the file
241+was copied up to will now have a new mtime: so after a successful copy-up,
242+we sync up with the new top-level branch's parent directory mtime.
243+
244+Implementation:
245+
246+This cache-coherency implementation is efficient because it defers any
247+synchronizing between the upper and lower layers until absolutely needed.
248+Consider the example a common situation where users perform a lot of lower
249+changes, such as untarring a whole package. While these take place,
250+typically the user doesn't access the files via Unionfs; only after the
251+lower changes are done, does the user try to access the lower files. With
252+our cache-coherency implementation, the entirety of the changes to the lower
253+branches will not result in a single CPU cycle spent at the Unionfs level
254+until the user invokes a system call that goes through Unionfs.
255+
256+We have considered two alternate cache-coherency designs. (1) Using the
257+dentry/inode notify functionality to register interest in finding out about
258+any lower changes. This is a somewhat limited and also a heavy-handed
259+approach which could result in many notifications to the Unionfs layer upon
260+each small change at the lower layer (imagine a file being modified multiple
261+times in rapid succession). (2) Rewriting the VFS to support explicit
262+callbacks from lower objects to upper objects. We began exploring such an
263+implementation, but found it to be very complicated--it would have resulted
264+in massive VFS/MM changes which are unlikely to be accepted by the LKML
265+community. We therefore believe that our current cache-coherency design and
266+implementation represent the best approach at this time.
267+
268+Limitations:
269+
270+Our implementation works in that as long as a user process will have caused
271+Unionfs to be called, directly or indirectly, even to just do
272+->d_revalidate; then we will have purged the current Unionfs data and the
273+process will see the new data. For example, a process that continually
274+re-reads the same file's data will see the NEW data as soon as the lower
275+file had changed, upon the next read(2) syscall (even if the file is still
276+open!) However, this doesn't work when the process re-reads the open file's
277+data via mmap(2) (unless the user unmaps/closes the file and remaps/reopens
278+it). Once we respond to ->readpage(s), then the kernel maps the page into
279+the process's address space and there doesn't appear to be a way to force
280+the kernel to invalidate those pages/mappings, and force the process to
281+re-issue ->readpage. If there's a way to invalidate active mappings and
282+force a ->readpage, let us know please (invalidate_inode_pages2 doesn't do
283+the trick).
284+
285+Our current Unionfs code has to perform many file-revalidation calls. It
286+would be really nice if the VFS would export an optional file system hook
287+->file_revalidate (similarly to dentry->d_revalidate) that will be called
288+before each VFS op that has a "struct file" in it.
289+
290+Certain file systems have micro-second granularity (or better) for inode
291+times, and asynchronous actions could cause those times to change with some
292+small delay. In such cases, Unionfs may see a changed inode time that only
293+differs by a tiny fraction of a second: such a change may be a false
294+positive indication that the lower object has changed, whereas if unionfs
295+waits a little longer, that false indication will not be seen. (These false
296+positives are harmless, because they would at most cause unionfs to
297+re-validate an object that may need no revalidation, and print a debugging
298+message that clutters the console/logs.) Therefore, to minimize the chances
299+of these situations, we delay the detection of changed times by a small
300+factor of a few seconds, called UNIONFS_MIN_CC_TIME (which defaults to 3
301+seconds, as does NFS). This means that we will detect the change, only a
302+couple of seconds later, if indeed the time change persists in the lower
303+file object. This delayed detection has an added performance benefit: we
304+reduce the number of times that unionfs has to revalidate objects, in case
305+there's a lot of concurrent activity on both the upper and lower objects,
306+for the same file(s). Lastly, this delayed time attribute detection is
307+similar to how NFS clients operate (e.g., acregmin).
308+
309+Finally, there is no way currently in Linux to prevent lower directories
310+from being moved around (i.e., topology changes); there's no way to prevent
311+modifications to directory sub-trees of whole file systems which are mounted
312+read-write. It is therefore possible for in-flight operations in unionfs to
313+take place, while a lower directory is being moved around. Therefore, if
314+you try to, say, create a new file in a directory through unionfs, while the
315+directory is being moved around directly, then the new file may get created
316+in the new location where that directory was moved to. This is a somewhat
317+similar behaviour in NFS: an NFS client could be creating a new file while
318+th NFS server is moving th directory around; the file will get successfully
319+created in the new location. (The one exception in unionfs is that if the
320+branch is marked read-only by unionfs, then a copyup will take place.)
321+
322+For more information, see <http://unionfs.filesystems.org/>.
323diff --git a/Documentation/filesystems/unionfs/issues.txt b/Documentation/filesystems/unionfs/issues.txt
324new file mode 100644
325index 0000000..f4b7e7e
326--- /dev/null
327+++ b/Documentation/filesystems/unionfs/issues.txt
328@@ -0,0 +1,28 @@
329+KNOWN Unionfs 2.x ISSUES:
330+=========================
331+
332+1. Unionfs should not use lookup_one_len() on the underlying f/s as it
333+ confuses NFSv4. Currently, unionfs_lookup() passes lookup intents to the
334+ lower file-system, this eliminates part of the problem. The remaining
335+ calls to lookup_one_len may need to be changed to pass an intent. We are
336+ currently introducing VFS changes to fs/namei.c's do_path_lookup() to
337+ allow proper file lookup and opening in stackable file systems.
338+
339+2. Lockdep (a debugging feature) isn't aware of stacking, and so it
340+ incorrectly complains about locking problems. The problem boils down to
341+ this: Lockdep considers all objects of a certain type to be in the same
342+ class, for example, all inodes. Lockdep doesn't like to see a lock held
343+ on two inodes within the same task, and warns that it could lead to a
344+ deadlock. However, stackable file systems do precisely that: they lock
345+ an upper object, and then a lower object, in a strict order to avoid
346+ locking problems; in addition, Unionfs, as a fan-out file system, may
347+ have to lock several lower inodes. We are currently looking into Lockdep
348+ to see how to make it aware of stackable file systems. For now, we
349+ temporarily disable lockdep when calling vfs methods on lower objects,
350+ but only for those places where lockdep complained. While this solution
351+ may seem unclean, it is not without precedent: other places in the kernel
352+ also do similar temporary disabling, of course after carefully having
353+ checked that it is the right thing to do. Anyway, you get any warnings
354+ from Lockdep, please report them to the Unionfs maintainers.
355+
356+For more information, see <http://unionfs.filesystems.org/>.
357diff --git a/Documentation/filesystems/unionfs/rename.txt b/Documentation/filesystems/unionfs/rename.txt
358new file mode 100644
359index 0000000..e20bb82
360--- /dev/null
361+++ b/Documentation/filesystems/unionfs/rename.txt
362@@ -0,0 +1,31 @@
363+Rename is a complex beast. The following table shows which rename(2) operations
364+should succeed and which should fail.
365+
366+o: success
367+E: error (either unionfs or vfs)
368+X: EXDEV
369+
370+none = file does not exist
371+file = file is a file
372+dir = file is a empty directory
373+child= file is a non-empty directory
374+wh = file is a directory containing only whiteouts; this makes it logically
375+ empty
376+
377+ none file dir child wh
378+file o o E E E
379+dir o E o E o
380+child X E X E X
381+wh o E o E o
382+
383+
384+Renaming directories:
385+=====================
386+
387+Whenever a empty (either physically or logically) directory is being renamed,
388+the following sequence of events should take place:
389+
390+1) Remove whiteouts from both source and destination directory
391+2) Rename source to destination
392+3) Make destination opaque to prevent anything under it from showing up
393+
394diff --git a/Documentation/filesystems/unionfs/usage.txt b/Documentation/filesystems/unionfs/usage.txt
395new file mode 100644
396index 0000000..1adde69
397--- /dev/null
398+++ b/Documentation/filesystems/unionfs/usage.txt
399@@ -0,0 +1,134 @@
400+Unionfs is a stackable unification file system, which can appear to merge
401+the contents of several directories (branches), while keeping their physical
402+content separate. Unionfs is useful for unified source tree management,
403+merged contents of split CD-ROM, merged separate software package
404+directories, data grids, and more. Unionfs allows any mix of read-only and
405+read-write branches, as well as insertion and deletion of branches anywhere
406+in the fan-out. To maintain Unix semantics, Unionfs handles elimination of
407+duplicates, partial-error conditions, and more.
408+
409+GENERAL SYNTAX
410+==============
411+
412+# mount -t unionfs -o <OPTIONS>,<BRANCH-OPTIONS> none MOUNTPOINT
413+
414+OPTIONS can be any legal combination of:
415+
416+- ro # mount file system read-only
417+- rw # mount file system read-write
418+- remount # remount the file system (see Branch Management below)
419+- incgen # increment generation no. (see Cache Consistency below)
420+
421+BRANCH-OPTIONS can be either (1) a list of branches given to the "dirs="
422+option, or (2) a list of individual branch manipulation commands, combined
423+with the "remount" option, and is further described in the "Branch
424+Management" section below.
425+
426+The syntax for the "dirs=" mount option is:
427+
428+ dirs=branch[=ro|=rw][:...]
429+
430+The "dirs=" option takes a colon-delimited list of directories to compose
431+the union, with an optional branch mode for each of those directories.
432+Directories that come earlier (specified first, on the left) in the list
433+have a higher precedence than those which come later. Additionally,
434+read-only or read-write permissions of the branch can be specified by
435+appending =ro or =rw (default) to each directory. See the Copyup section in
436+concepts.txt, for a description of Unionfs's behavior when mixing read-only
437+and read-write branches and mounts.
438+
439+Syntax:
440+
441+ dirs=/branch1[=ro|=rw]:/branch2[=ro|=rw]:...:/branchN[=ro|=rw]
442+
443+Example:
444+
445+ dirs=/writable_branch=rw:/read-only_branch=ro
446+
447+
448+BRANCH MANAGEMENT
449+=================
450+
451+Once you mount your union for the first time, using the "dirs=" option, you
452+can then change the union's overall mode or reconfigure the branches, using
453+the remount option, as follows.
454+
455+To downgrade a union from read-write to read-only:
456+
457+# mount -t unionfs -o remount,ro none MOUNTPOINT
458+
459+To upgrade a union from read-only to read-write:
460+
461+# mount -t unionfs -o remount,rw none MOUNTPOINT
462+
463+To delete a branch /foo, regardless where it is in the current union:
464+
465+# mount -t unionfs -o remount,del=/foo none MOUNTPOINT
466+
467+To insert (add) a branch /foo before /bar:
468+
469+# mount -t unionfs -o remount,add=/bar:/foo none MOUNTPOINT
470+
471+To insert (add) a branch /foo (with the "rw" mode flag) before /bar:
472+
473+# mount -t unionfs -o remount,add=/bar:/foo=rw none MOUNTPOINT
474+
475+To insert (add) a branch /foo (in "rw" mode) at the very beginning (i.e., a
476+new highest-priority branch), you can use the above syntax, or use a short
477+hand version as follows:
478+
479+# mount -t unionfs -o remount,add=/foo none MOUNTPOINT
480+
481+To append a branch to the very end (new lowest-priority branch):
482+
483+# mount -t unionfs -o remount,add=:/foo none MOUNTPOINT
484+
485+To append a branch to the very end (new lowest-priority branch), in
486+read-only mode:
487+
488+# mount -t unionfs -o remount,add=:/foo=ro none MOUNTPOINT
489+
490+Finally, to change the mode of one existing branch, say /foo, from read-only
491+to read-write, and change /bar from read-write to read-only:
492+
493+# mount -t unionfs -o remount,mode=/foo=rw,mode=/bar=ro none MOUNTPOINT
494+
495+Note: in Unionfs 2.x, you cannot set the leftmost branch to readonly because
496+then Unionfs won't have any writable place for copyups to take place.
497+Moreover, the VFS can get confused when it tries to modify something in a
498+file system mounted read-write, but isn't permitted to write to it.
499+Instead, you should set the whole union as readonly, as described above.
500+If, however, you must set the leftmost branch as readonly, perhaps so you
501+can get a snapshot of it at a point in time, then you should insert a new
502+writable top-level branch, and mark the one you want as readonly. This can
503+be accomplished as follows, assuming that /foo is your current leftmost
504+branch:
505+
506+# mount -t tmpfs -o size=NNN /new
507+# mount -t unionfs -o remount,add=/new,mode=/foo=ro none MOUNTPOINT
508+<do what you want safely in /foo>
509+# mount -t unionfs -o remount,del=/new,mode=/foo=rw none MOUNTPOINT
510+<check if there's anything in /new you want to preserve>
511+# umount /new
512+
513+CACHE CONSISTENCY
514+=================
515+
516+If you modify any file on any of the lower branches directly, while there is
517+a Unionfs 2.x mounted above any of those branches, you should tell Unionfs
518+to purge its caches and re-get the objects. To do that, you have to
519+increment the generation number of the superblock using the following
520+command:
521+
522+# mount -t unionfs -o remount,incgen none MOUNTPOINT
523+
524+Note that the older way of incrementing the generation number using an
525+ioctl, is no longer supported in Unionfs 2.0 and newer. Ioctls in general
526+are not encouraged. Plus, an ioctl is per-file concept, whereas the
527+generation number is a per-file-system concept. Worse, such an ioctl
528+requires an open file, which then has to be invalidated by the very nature
529+of the generation number increase (read: the old generation increase ioctl
530+was pretty racy).
531+
532+
533+For more information, see <http://unionfs.filesystems.org/>.
534diff --git a/MAINTAINERS b/MAINTAINERS
535index deedc0d..c722f8e 100644
536--- a/MAINTAINERS
537+++ b/MAINTAINERS
538@@ -4173,6 +4173,14 @@ L: linux-kernel@vger.kernel.org
539 W: http://www.kernel.dk
540 S: Maintained
541
542+UNIONFS
543+P: Erez Zadok
544+M: ezk@cs.sunysb.edu
545+L: unionfs@filesystems.org
546+W: http://unionfs.filesystems.org
547+T: git git.kernel.org/pub/scm/linux/kernel/git/ezk/unionfs.git
548+S: Maintained
549+
550 USB ACM DRIVER
551 P: Oliver Neukum
552 M: oliver@neukum.name
553diff --git a/fs/Kconfig b/fs/Kconfig
554index d387358..31610a2 100644
555--- a/fs/Kconfig
556+++ b/fs/Kconfig
557@@ -981,6 +981,47 @@ config CONFIGFS_FS
558
559 endmenu
560
561+menu "Layered filesystems"
562+
563+config ECRYPT_FS
564+ tristate "eCrypt filesystem layer support (EXPERIMENTAL)"
565+ depends on EXPERIMENTAL && KEYS && CRYPTO && NET
566+ help
567+ Encrypted filesystem that operates on the VFS layer. See
568+ <file:Documentation/filesystems/ecryptfs.txt> to learn more about
569+ eCryptfs. Userspace components are required and can be
570+ obtained from <http://ecryptfs.sf.net>.
571+
572+ To compile this file system support as a module, choose M here: the
573+ module will be called ecryptfs.
574+
575+config UNION_FS
576+ tristate "Union file system (EXPERIMENTAL)"
577+ depends on EXPERIMENTAL
578+ help
579+ Unionfs is a stackable unification file system, which appears to
580+ merge the contents of several directories (branches), while keeping
581+ their physical content separate.
582+
583+ See <http://unionfs.filesystems.org> for details
584+
585+config UNION_FS_XATTR
586+ bool "Unionfs extended attributes"
587+ depends on UNION_FS
588+ help
589+ Extended attributes are name:value pairs associated with inodes by
590+ the kernel or by users (see the attr(5) manual page).
591+
592+ If unsure, say N.
593+
594+config UNION_FS_DEBUG
595+ bool "Debug Unionfs"
596+ depends on UNION_FS
597+ help
598+ If you say Y here, you can turn on debugging output from Unionfs.
599+
600+endmenu
601+
602 menu "Miscellaneous filesystems"
603
604 config ADFS_FS
605@@ -1033,18 +1074,6 @@ config AFFS_FS
606 To compile this file system support as a module, choose M here: the
607 module will be called affs. If unsure, say N.
608
609-config ECRYPT_FS
610- tristate "eCrypt filesystem layer support (EXPERIMENTAL)"
611- depends on EXPERIMENTAL && KEYS && CRYPTO && NET
612- help
613- Encrypted filesystem that operates on the VFS layer. See
614- <file:Documentation/filesystems/ecryptfs.txt> to learn more about
615- eCryptfs. Userspace components are required and can be
616- obtained from <http://ecryptfs.sf.net>.
617-
618- To compile this file system support as a module, choose M here: the
619- module will be called ecryptfs.
620-
621 config HFS_FS
622 tristate "Apple Macintosh file system support (EXPERIMENTAL)"
623 depends on BLOCK && EXPERIMENTAL
624diff --git a/fs/Makefile b/fs/Makefile
625index a1482a5..9bf3915 100644
626--- a/fs/Makefile
627+++ b/fs/Makefile
628@@ -86,6 +86,7 @@ obj-$(CONFIG_ISO9660_FS) += isofs/
629 obj-$(CONFIG_HFSPLUS_FS) += hfsplus/ # Before hfs to find wrapped HFS+
630 obj-$(CONFIG_HFS_FS) += hfs/
631 obj-$(CONFIG_ECRYPT_FS) += ecryptfs/
632+obj-$(CONFIG_UNION_FS) += unionfs/
633 obj-$(CONFIG_VXFS_FS) += freevxfs/
634 obj-$(CONFIG_NFS_FS) += nfs/
635 obj-$(CONFIG_EXPORTFS) += exportfs/
636diff --git a/fs/ecryptfs/dentry.c b/fs/ecryptfs/dentry.c
637index 5e59658..4621f89 100644
638--- a/fs/ecryptfs/dentry.c
639+++ b/fs/ecryptfs/dentry.c
640@@ -62,7 +62,7 @@ static int ecryptfs_d_revalidate(struct dentry *dentry, struct nameidata *nd)
641 struct inode *lower_inode =
642 ecryptfs_inode_to_lower(dentry->d_inode);
643
644- fsstack_copy_attr_all(dentry->d_inode, lower_inode, NULL);
645+ fsstack_copy_attr_all(dentry->d_inode, lower_inode);
646 }
647 out:
648 return rc;
649diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c
650index 89209f0..d99a83e 100644
651--- a/fs/ecryptfs/inode.c
652+++ b/fs/ecryptfs/inode.c
653@@ -589,9 +589,9 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry,
654 lower_new_dir_dentry->d_inode, lower_new_dentry);
655 if (rc)
656 goto out_lock;
657- fsstack_copy_attr_all(new_dir, lower_new_dir_dentry->d_inode, NULL);
658+ fsstack_copy_attr_all(new_dir, lower_new_dir_dentry->d_inode);
659 if (new_dir != old_dir)
660- fsstack_copy_attr_all(old_dir, lower_old_dir_dentry->d_inode, NULL);
661+ fsstack_copy_attr_all(old_dir, lower_old_dir_dentry->d_inode);
662 out_lock:
663 unlock_rename(lower_old_dir_dentry, lower_new_dir_dentry);
664 dput(lower_new_dentry->d_parent);
665@@ -913,7 +913,7 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia)
666 rc = notify_change(lower_dentry, ia);
667 mutex_unlock(&lower_dentry->d_inode->i_mutex);
668 out:
669- fsstack_copy_attr_all(inode, lower_inode, NULL);
670+ fsstack_copy_attr_all(inode, lower_inode);
671 return rc;
672 }
673
674diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c
675index 448dfd5..db2db5d 100644
676--- a/fs/ecryptfs/main.c
677+++ b/fs/ecryptfs/main.c
678@@ -197,7 +197,7 @@ int ecryptfs_interpose(struct dentry *lower_dentry, struct dentry *dentry,
679 d_add(dentry, inode);
680 else
681 d_instantiate(dentry, inode);
682- fsstack_copy_attr_all(inode, lower_inode, NULL);
683+ fsstack_copy_attr_all(inode, lower_inode);
684 /* This size will be overwritten for real files w/ headers and
685 * other metadata */
686 fsstack_copy_inode_size(inode, lower_inode);
687diff --git a/fs/namei.c b/fs/namei.c
688index a7b0a0b..d05ee31 100644
689--- a/fs/namei.c
690+++ b/fs/namei.c
691@@ -392,6 +392,7 @@ void release_open_intent(struct nameidata *nd)
692 else
693 fput(nd->intent.open.file);
694 }
695+EXPORT_SYMBOL_GPL(release_open_intent);
696
697 static inline struct dentry *
698 do_revalidate(struct dentry *dentry, struct nameidata *nd)
699diff --git a/fs/splice.c b/fs/splice.c
700index b30311b..204bb3c 100644
701--- a/fs/splice.c
702+++ b/fs/splice.c
703@@ -887,8 +887,8 @@ EXPORT_SYMBOL(generic_splice_sendpage);
704 /*
705 * Attempt to initiate a splice from pipe to file.
706 */
707-static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
708- loff_t *ppos, size_t len, unsigned int flags)
709+long vfs_splice_from(struct pipe_inode_info *pipe, struct file *out,
710+ loff_t *ppos, size_t len, unsigned int flags)
711 {
712 int ret;
713
714@@ -904,13 +904,14 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out,
715
716 return out->f_op->splice_write(pipe, out, ppos, len, flags);
717 }
718+EXPORT_SYMBOL_GPL(vfs_splice_from);
719
720 /*
721 * Attempt to initiate a splice from a file to a pipe.
722 */
723-static long do_splice_to(struct file *in, loff_t *ppos,
724- struct pipe_inode_info *pipe, size_t len,
725- unsigned int flags)
726+long vfs_splice_to(struct file *in, loff_t *ppos,
727+ struct pipe_inode_info *pipe, size_t len,
728+ unsigned int flags)
729 {
730 int ret;
731
732@@ -926,6 +927,7 @@ static long do_splice_to(struct file *in, loff_t *ppos,
733
734 return in->f_op->splice_read(in, ppos, pipe, len, flags);
735 }
736+EXPORT_SYMBOL_GPL(vfs_splice_to);
737
738 /**
739 * splice_direct_to_actor - splices data directly between two non-pipes
740@@ -995,7 +997,7 @@ ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd,
741 size_t read_len;
742 loff_t pos = sd->pos, prev_pos = pos;
743
744- ret = do_splice_to(in, &pos, pipe, len, flags);
745+ ret = vfs_splice_to(in, &pos, pipe, len, flags);
746 if (unlikely(ret <= 0))
747 goto out_release;
748
749@@ -1054,7 +1056,7 @@ static int direct_splice_actor(struct pipe_inode_info *pipe,
750 {
751 struct file *file = sd->u.file;
752
753- return do_splice_from(pipe, file, &sd->pos, sd->total_len, sd->flags);
754+ return vfs_splice_from(pipe, file, &sd->pos, sd->total_len, sd->flags);
755 }
756
757 /**
758@@ -1128,7 +1130,7 @@ static long do_splice(struct file *in, loff_t __user *off_in,
759 } else
760 off = &out->f_pos;
761
762- ret = do_splice_from(pipe, out, off, len, flags);
763+ ret = vfs_splice_from(pipe, out, off, len, flags);
764
765 if (off_out && copy_to_user(off_out, off, sizeof(loff_t)))
766 ret = -EFAULT;
767@@ -1149,7 +1151,7 @@ static long do_splice(struct file *in, loff_t __user *off_in,
768 } else
769 off = &in->f_pos;
770
771- ret = do_splice_to(in, off, pipe, len, flags);
772+ ret = vfs_splice_to(in, off, pipe, len, flags);
773
774 if (off_in && copy_to_user(off_in, off, sizeof(loff_t)))
775 ret = -EFAULT;
776diff --git a/fs/stack.c b/fs/stack.c
777index 67716f6..a66ff6c 100644
778--- a/fs/stack.c
779+++ b/fs/stack.c
780@@ -1,24 +1,82 @@
781+/*
782+ * Copyright (c) 2006-2007 Erez Zadok
783+ * Copyright (c) 2006-2007 Josef 'Jeff' Sipek
784+ * Copyright (c) 2006-2007 Stony Brook University
785+ * Copyright (c) 2006-2007 The Research Foundation of SUNY
786+ *
787+ * This program is free software; you can redistribute it and/or modify
788+ * it under the terms of the GNU General Public License version 2 as
789+ * published by the Free Software Foundation.
790+ */
791+
792 #include <linux/module.h>
793 #include <linux/fs.h>
794 #include <linux/fs_stack.h>
795
796-/* does _NOT_ require i_mutex to be held.
797+/*
798+ * does _NOT_ require i_mutex to be held.
799 *
800 * This function cannot be inlined since i_size_{read,write} is rather
801 * heavy-weight on 32-bit systems
802 */
803-void fsstack_copy_inode_size(struct inode *dst, const struct inode *src)
804+void fsstack_copy_inode_size(struct inode *dst, struct inode *src)
805 {
806- i_size_write(dst, i_size_read((struct inode *)src));
807- dst->i_blocks = src->i_blocks;
808+ loff_t i_size;
809+ blkcnt_t i_blocks;
810+
811+ /*
812+ * i_size_read() includes its own seqlocking and protection from
813+ * preemption (see include/linux/fs.h): we need nothing extra for
814+ * that here, and prefer to avoid nesting locks than attempt to
815+ * keep i_size and i_blocks in synch together.
816+ */
817+ i_size = i_size_read(src);
818+
819+ /*
820+ * But if CONFIG_LSF (on 32-bit), we ought to make an effort to keep
821+ * the two halves of i_blocks in synch despite SMP or PREEMPT - though
822+ * stat's generic_fillattr() doesn't bother, and we won't be applying
823+ * quotas (where i_blocks does become important) at the upper level.
824+ *
825+ * We don't actually know what locking is used at the lower level; but
826+ * if it's a filesystem that supports quotas, it will be using i_lock
827+ * as in inode_add_bytes(). tmpfs uses other locking, and its 32-bit
828+ * is (just) able to exceed 2TB i_size with the aid of holes; but its
829+ * i_blocks cannot carry into the upper long without almost 2TB swap -
830+ * let's ignore that case.
831+ */
832+ if (sizeof(i_blocks) > sizeof(long))
833+ spin_lock(&src->i_lock);
834+ i_blocks = src->i_blocks;
835+ if (sizeof(i_blocks) > sizeof(long))
836+ spin_unlock(&src->i_lock);
837+
838+ /*
839+ * If CONFIG_SMP on 32-bit, it's vital for fsstack_copy_inode_size()
840+ * to hold some lock around i_size_write(), otherwise i_size_read()
841+ * may spin forever (see include/linux/fs.h). We don't necessarily
842+ * hold i_mutex when this is called, so take i_lock for that case.
843+ *
844+ * And if CONFIG_LSF (on 32-bit), continue our effort to keep the
845+ * two halves of i_blocks in synch despite SMP or PREEMPT: use i_lock
846+ * for that case too, and do both at once by combining the tests.
847+ *
848+ * There is none of this locking overhead in the 64-bit case.
849+ */
850+ if (sizeof(i_size) > sizeof(long) || sizeof(i_blocks) > sizeof(long))
851+ spin_lock(&dst->i_lock);
852+ i_size_write(dst, i_size);
853+ dst->i_blocks = i_blocks;
854+ if (sizeof(i_size) > sizeof(long) || sizeof(i_blocks) > sizeof(long))
855+ spin_unlock(&dst->i_lock);
856 }
857 EXPORT_SYMBOL_GPL(fsstack_copy_inode_size);
858
859-/* copy all attributes; get_nlinks is optional way to override the i_nlink
860+/*
861+ * copy all attributes; get_nlinks is optional way to override the i_nlink
862 * copying
863 */
864-void fsstack_copy_attr_all(struct inode *dest, const struct inode *src,
865- int (*get_nlinks)(struct inode *))
866+void fsstack_copy_attr_all(struct inode *dest, const struct inode *src)
867 {
868 dest->i_mode = src->i_mode;
869 dest->i_uid = src->i_uid;
870@@ -29,14 +87,6 @@ void fsstack_copy_attr_all(struct inode *dest, const struct inode *src,
871 dest->i_ctime = src->i_ctime;
872 dest->i_blkbits = src->i_blkbits;
873 dest->i_flags = src->i_flags;
874-
875- /*
876- * Update the nlinks AFTER updating the above fields, because the
877- * get_links callback may depend on them.
878- */
879- if (!get_nlinks)
880- dest->i_nlink = src->i_nlink;
881- else
882- dest->i_nlink = (*get_nlinks)(dest);
883+ dest->i_nlink = src->i_nlink;
884 }
885 EXPORT_SYMBOL_GPL(fsstack_copy_attr_all);
886diff --git a/fs/unionfs/Makefile b/fs/unionfs/Makefile
887new file mode 100644
888index 0000000..fa04e30
889--- /dev/null
890+++ b/fs/unionfs/Makefile
891@@ -0,0 +1,17 @@
892+UNIONFS_VERSION="2.4 (for 2.6.27-rc1)"
893+
894+EXTRA_CFLAGS += -DUNIONFS_VERSION=\"$(UNIONFS_VERSION)\"
895+
896+obj-$(CONFIG_UNION_FS) += unionfs.o
897+
898+unionfs-y := subr.o dentry.o file.o inode.o main.o super.o \
899+ rdstate.o copyup.o dirhelper.o rename.o unlink.o \
900+ lookup.o commonfops.o dirfops.o sioq.o mmap.o whiteout.o
901+
902+unionfs-$(CONFIG_UNION_FS_XATTR) += xattr.o
903+
904+unionfs-$(CONFIG_UNION_FS_DEBUG) += debug.o
905+
906+ifeq ($(CONFIG_UNION_FS_DEBUG),y)
907+EXTRA_CFLAGS += -DDEBUG
908+endif
909diff --git a/fs/unionfs/commonfops.c b/fs/unionfs/commonfops.c
910new file mode 100644
911index 0000000..5861970
912--- /dev/null
913+++ b/fs/unionfs/commonfops.c
914@@ -0,0 +1,905 @@
915+/*
916+ * Copyright (c) 2003-2008 Erez Zadok
917+ * Copyright (c) 2003-2006 Charles P. Wright
918+ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
919+ * Copyright (c) 2005-2006 Junjiro Okajima
920+ * Copyright (c) 2005 Arun M. Krishnakumar
921+ * Copyright (c) 2004-2006 David P. Quigley
922+ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
923+ * Copyright (c) 2003 Puja Gupta
924+ * Copyright (c) 2003 Harikesavan Krishnan
925+ * Copyright (c) 2003-2008 Stony Brook University
926+ * Copyright (c) 2003-2008 The Research Foundation of SUNY
927+ *
928+ * This program is free software; you can redistribute it and/or modify
929+ * it under the terms of the GNU General Public License version 2 as
930+ * published by the Free Software Foundation.
931+ */
932+
933+#include "union.h"
934+
935+/*
936+ * 1) Copyup the file
937+ * 2) Rename the file to '.unionfs<original inode#><counter>' - obviously
938+ * stolen from NFS's silly rename
939+ */
940+static int copyup_deleted_file(struct file *file, struct dentry *dentry,
941+ int bstart, int bindex)
942+{
943+ static unsigned int counter;
944+ const int i_inosize = sizeof(dentry->d_inode->i_ino) * 2;
945+ const int countersize = sizeof(counter) * 2;
946+ const int nlen = sizeof(".unionfs") + i_inosize + countersize - 1;
947+ char name[nlen + 1];
948+ int err;
949+ struct dentry *tmp_dentry = NULL;
950+ struct dentry *lower_dentry;
951+ struct dentry *lower_dir_dentry = NULL;
952+
953+ lower_dentry = unionfs_lower_dentry_idx(dentry, bstart);
954+
955+ sprintf(name, ".unionfs%*.*lx",
956+ i_inosize, i_inosize, lower_dentry->d_inode->i_ino);
957+
958+ /*
959+ * Loop, looking for an unused temp name to copyup to.
960+ *
961+ * It's somewhat silly that we look for a free temp tmp name in the
962+ * source branch (bstart) instead of the dest branch (bindex), where
963+ * the final name will be created. We _will_ catch it if somehow
964+ * the name exists in the dest branch, but it'd be nice to catch it
965+ * sooner than later.
966+ */
967+retry:
968+ tmp_dentry = NULL;
969+ do {
970+ char *suffix = name + nlen - countersize;
971+
972+ dput(tmp_dentry);
973+ counter++;
974+ sprintf(suffix, "%*.*x", countersize, countersize, counter);
975+
976+ pr_debug("unionfs: trying to rename %s to %s\n",
977+ dentry->d_name.name, name);
978+
979+ tmp_dentry = lookup_one_len(name, lower_dentry->d_parent,
980+ nlen);
981+ if (IS_ERR(tmp_dentry)) {
982+ err = PTR_ERR(tmp_dentry);
983+ goto out;
984+ }
985+ } while (tmp_dentry->d_inode != NULL); /* need negative dentry */
986+ dput(tmp_dentry);
987+
988+ err = copyup_named_file(dentry->d_parent->d_inode, file, name, bstart,
989+ bindex,
990+ i_size_read(file->f_path.dentry->d_inode));
991+ if (err) {
992+ if (unlikely(err == -EEXIST))
993+ goto retry;
994+ goto out;
995+ }
996+
997+ /* bring it to the same state as an unlinked file */
998+ lower_dentry = unionfs_lower_dentry_idx(dentry, dbstart(dentry));
999+ if (!unionfs_lower_inode_idx(dentry->d_inode, bindex)) {
1000+ atomic_inc(&lower_dentry->d_inode->i_count);
1001+ unionfs_set_lower_inode_idx(dentry->d_inode, bindex,
1002+ lower_dentry->d_inode);
1003+ }
1004+ lower_dir_dentry = lock_parent(lower_dentry);
1005+ err = vfs_unlink(lower_dir_dentry->d_inode, lower_dentry);
1006+ unlock_dir(lower_dir_dentry);
1007+
1008+out:
1009+ if (!err)
1010+ unionfs_check_dentry(dentry);
1011+ return err;
1012+}
1013+
1014+/*
1015+ * put all references held by upper struct file and free lower file pointer
1016+ * array
1017+ */
1018+static void cleanup_file(struct file *file)
1019+{
1020+ int bindex, bstart, bend;
1021+ struct file **lower_files;
1022+ struct file *lower_file;
1023+ struct super_block *sb = file->f_path.dentry->d_sb;
1024+
1025+ lower_files = UNIONFS_F(file)->lower_files;
1026+ bstart = fbstart(file);
1027+ bend = fbend(file);
1028+
1029+ for (bindex = bstart; bindex <= bend; bindex++) {
1030+ int i; /* holds (possibly) updated branch index */
1031+ int old_bid;
1032+
1033+ lower_file = unionfs_lower_file_idx(file, bindex);
1034+ if (!lower_file)
1035+ continue;
1036+
1037+ /*
1038+ * Find new index of matching branch with an open
1039+ * file, since branches could have been added or
1040+ * deleted causing the one with open files to shift.
1041+ */
1042+ old_bid = UNIONFS_F(file)->saved_branch_ids[bindex];
1043+ i = branch_id_to_idx(sb, old_bid);
1044+ if (unlikely(i < 0)) {
1045+ printk(KERN_ERR "unionfs: no superblock for "
1046+ "file %p\n", file);
1047+ continue;
1048+ }
1049+
1050+ /* decrement count of open files */
1051+ branchput(sb, i);
1052+ /*
1053+ * fput will perform an mntput for us on the correct branch.
1054+ * Although we're using the file's old branch configuration,
1055+ * bindex, which is the old index, correctly points to the
1056+ * right branch in the file's branch list. In other words,
1057+ * we're going to mntput the correct branch even if branches
1058+ * have been added/removed.
1059+ */
1060+ fput(lower_file);
1061+ UNIONFS_F(file)->lower_files[bindex] = NULL;
1062+ UNIONFS_F(file)->saved_branch_ids[bindex] = -1;
1063+ }
1064+
1065+ UNIONFS_F(file)->lower_files = NULL;
1066+ kfree(lower_files);
1067+ kfree(UNIONFS_F(file)->saved_branch_ids);
1068+ /* set to NULL because caller needs to know if to kfree on error */
1069+ UNIONFS_F(file)->saved_branch_ids = NULL;
1070+}
1071+
1072+/* open all lower files for a given file */
1073+static int open_all_files(struct file *file)
1074+{
1075+ int bindex, bstart, bend, err = 0;
1076+ struct file *lower_file;
1077+ struct dentry *lower_dentry;
1078+ struct dentry *dentry = file->f_path.dentry;
1079+ struct super_block *sb = dentry->d_sb;
1080+
1081+ bstart = dbstart(dentry);
1082+ bend = dbend(dentry);
1083+
1084+ for (bindex = bstart; bindex <= bend; bindex++) {
1085+ lower_dentry = unionfs_lower_dentry_idx(dentry, bindex);
1086+ if (!lower_dentry)
1087+ continue;
1088+
1089+ dget(lower_dentry);
1090+ unionfs_mntget(dentry, bindex);
1091+ branchget(sb, bindex);
1092+
1093+ lower_file =
1094+ dentry_open(lower_dentry,
1095+ unionfs_lower_mnt_idx(dentry, bindex),
1096+ file->f_flags);
1097+ if (IS_ERR(lower_file)) {
1098+ err = PTR_ERR(lower_file);
1099+ goto out;
1100+ } else {
1101+ unionfs_set_lower_file_idx(file, bindex, lower_file);
1102+ }
1103+ }
1104+out:
1105+ return err;
1106+}
1107+
1108+/* open the highest priority file for a given upper file */
1109+static int open_highest_file(struct file *file, bool willwrite)
1110+{
1111+ int bindex, bstart, bend, err = 0;
1112+ struct file *lower_file;
1113+ struct dentry *lower_dentry;
1114+ struct dentry *dentry = file->f_path.dentry;
1115+ struct inode *parent_inode = dentry->d_parent->d_inode;
1116+ struct super_block *sb = dentry->d_sb;
1117+
1118+ bstart = dbstart(dentry);
1119+ bend = dbend(dentry);
1120+
1121+ lower_dentry = unionfs_lower_dentry(dentry);
1122+ if (willwrite && IS_WRITE_FLAG(file->f_flags) && is_robranch(dentry)) {
1123+ for (bindex = bstart - 1; bindex >= 0; bindex--) {
1124+ err = copyup_file(parent_inode, file, bstart, bindex,
1125+ i_size_read(dentry->d_inode));
1126+ if (!err)
1127+ break;
1128+ }
1129+ atomic_set(&UNIONFS_F(file)->generation,
1130+ atomic_read(&UNIONFS_I(dentry->d_inode)->
1131+ generation));
1132+ goto out;
1133+ }
1134+
1135+ dget(lower_dentry);
1136+ unionfs_mntget(dentry, bstart);
1137+ lower_file = dentry_open(lower_dentry,
1138+ unionfs_lower_mnt_idx(dentry, bstart),
1139+ file->f_flags);
1140+ if (IS_ERR(lower_file)) {
1141+ err = PTR_ERR(lower_file);
1142+ goto out;
1143+ }
1144+ branchget(sb, bstart);
1145+ unionfs_set_lower_file(file, lower_file);
1146+ /* Fix up the position. */
1147+ lower_file->f_pos = file->f_pos;
1148+
1149+ memcpy(&lower_file->f_ra, &file->f_ra, sizeof(struct file_ra_state));
1150+out:
1151+ return err;
1152+}
1153+
1154+/* perform a delayed copyup of a read-write file on a read-only branch */
1155+static int do_delayed_copyup(struct file *file)
1156+{
1157+ int bindex, bstart, bend, err = 0;
1158+ struct dentry *dentry = file->f_path.dentry;
1159+ struct inode *parent_inode = dentry->d_parent->d_inode;
1160+
1161+ bstart = fbstart(file);
1162+ bend = fbend(file);
1163+
1164+ BUG_ON(!S_ISREG(dentry->d_inode->i_mode));
1165+
1166+ unionfs_check_file(file);
1167+ for (bindex = bstart - 1; bindex >= 0; bindex--) {
1168+ if (!d_deleted(dentry))
1169+ err = copyup_file(parent_inode, file, bstart,
1170+ bindex,
1171+ i_size_read(dentry->d_inode));
1172+ else
1173+ err = copyup_deleted_file(file, dentry, bstart,
1174+ bindex);
1175+ /* if succeeded, set lower open-file flags and break */
1176+ if (!err) {
1177+ struct file *lower_file;
1178+ lower_file = unionfs_lower_file_idx(file, bindex);
1179+ lower_file->f_flags = file->f_flags;
1180+ break;
1181+ }
1182+ }
1183+ if (err || (bstart <= fbstart(file)))
1184+ goto out;
1185+ bend = fbend(file);
1186+ for (bindex = bstart; bindex <= bend; bindex++) {
1187+ if (unionfs_lower_file_idx(file, bindex)) {
1188+ branchput(dentry->d_sb, bindex);
1189+ fput(unionfs_lower_file_idx(file, bindex));
1190+ unionfs_set_lower_file_idx(file, bindex, NULL);
1191+ }
1192+ }
1193+ path_put_lowers(dentry, bstart, bend, false);
1194+ iput_lowers(dentry->d_inode, bstart, bend, false);
1195+ /* for reg file, we only open it "once" */
1196+ fbend(file) = fbstart(file);
1197+ dbend(dentry) = dbstart(dentry);
1198+ ibend(dentry->d_inode) = ibstart(dentry->d_inode);
1199+
1200+out:
1201+ unionfs_check_file(file);
1202+ return err;
1203+}
1204+
1205+/*
1206+ * Helper function for unionfs_file_revalidate/locked.
1207+ * Expects dentry/parent to be locked already, and revalidated.
1208+ */
1209+static int __unionfs_file_revalidate(struct file *file, struct dentry *dentry,
1210+ struct super_block *sb, int sbgen,
1211+ int dgen, bool willwrite)
1212+{
1213+ int fgen;
1214+ int bstart, bend, orig_brid;
1215+ int size;
1216+ int err = 0;
1217+
1218+ fgen = atomic_read(&UNIONFS_F(file)->generation);
1219+
1220+ /*
1221+ * There are two cases we are interested in. The first is if the
1222+ * generation is lower than the super-block. The second is if
1223+ * someone has copied up this file from underneath us, we also need
1224+ * to refresh things.
1225+ */
1226+ if (d_deleted(dentry) ||
1227+ (sbgen <= fgen &&
1228+ dbstart(dentry) == fbstart(file) &&
1229+ unionfs_lower_file(file)))
1230+ goto out_may_copyup;
1231+
1232+ /* save orig branch ID */
1233+ orig_brid = UNIONFS_F(file)->saved_branch_ids[fbstart(file)];
1234+
1235+ /* First we throw out the existing files. */
1236+ cleanup_file(file);
1237+
1238+ /* Now we reopen the file(s) as in unionfs_open. */
1239+ bstart = fbstart(file) = dbstart(dentry);
1240+ bend = fbend(file) = dbend(dentry);
1241+
1242+ size = sizeof(struct file *) * sbmax(sb);
1243+ UNIONFS_F(file)->lower_files = kzalloc(size, GFP_KERNEL);
1244+ if (unlikely(!UNIONFS_F(file)->lower_files)) {
1245+ err = -ENOMEM;
1246+ goto out;
1247+ }
1248+ size = sizeof(int) * sbmax(sb);
1249+ UNIONFS_F(file)->saved_branch_ids = kzalloc(size, GFP_KERNEL);
1250+ if (unlikely(!UNIONFS_F(file)->saved_branch_ids)) {
1251+ err = -ENOMEM;
1252+ goto out;
1253+ }
1254+
1255+ if (S_ISDIR(dentry->d_inode->i_mode)) {
1256+ /* We need to open all the files. */
1257+ err = open_all_files(file);
1258+ if (err)
1259+ goto out;
1260+ } else {
1261+ int new_brid;
1262+ /* We only open the highest priority branch. */
1263+ err = open_highest_file(file, willwrite);
1264+ if (err)
1265+ goto out;
1266+ new_brid = UNIONFS_F(file)->saved_branch_ids[fbstart(file)];
1267+ if (unlikely(new_brid != orig_brid && sbgen > fgen)) {
1268+ /*
1269+ * If we re-opened the file on a different branch
1270+ * than the original one, and this was due to a new
1271+ * branch inserted, then update the mnt counts of
1272+ * the old and new branches accordingly.
1273+ */
1274+ unionfs_mntget(dentry, bstart);
1275+ unionfs_mntput(sb->s_root,
1276+ branch_id_to_idx(sb, orig_brid));
1277+ }
1278+ /* regular files have only one open lower file */
1279+ fbend(file) = fbstart(file);
1280+ }
1281+ atomic_set(&UNIONFS_F(file)->generation,
1282+ atomic_read(&UNIONFS_I(dentry->d_inode)->generation));
1283+
1284+out_may_copyup:
1285+ /* Copyup on the first write to a file on a readonly branch. */
1286+ if (willwrite && IS_WRITE_FLAG(file->f_flags) &&
1287+ !IS_WRITE_FLAG(unionfs_lower_file(file)->f_flags) &&
1288+ is_robranch(dentry)) {
1289+ pr_debug("unionfs: do delay copyup of \"%s\"\n",
1290+ dentry->d_name.name);
1291+ err = do_delayed_copyup(file);
1292+ /* regular files have only one open lower file */
1293+ if (!err && !S_ISDIR(dentry->d_inode->i_mode))
1294+ fbend(file) = fbstart(file);
1295+ }
1296+
1297+out:
1298+ if (err) {
1299+ kfree(UNIONFS_F(file)->lower_files);
1300+ kfree(UNIONFS_F(file)->saved_branch_ids);
1301+ } else {
1302+ unionfs_check_file(file);
1303+ }
1304+ return err;
1305+}
1306+
1307+/*
1308+ * Revalidate the struct file
1309+ * @file: file to revalidate
1310+ * @willwrite: true if caller may cause changes to the file; false otherwise.
1311+ * Caller must lock/unlock dentry's branch configuration.
1312+ */
1313+int unionfs_file_revalidate(struct file *file, bool willwrite)
1314+{
1315+ struct super_block *sb;
1316+ struct dentry *dentry;
1317+ int sbgen, dgen;
1318+ int err = 0;
1319+
1320+ dentry = file->f_path.dentry;
1321+ sb = dentry->d_sb;
1322+ verify_locked(dentry);
1323+
1324+ /*
1325+ * First revalidate the dentry inside struct file,
1326+ * but not unhashed dentries.
1327+ */
1328+reval_dentry:
1329+ if (!d_deleted(dentry) &&
1330+ !__unionfs_d_revalidate_chain(dentry, NULL, willwrite)) {
1331+ err = -ESTALE;
1332+ goto out;
1333+ }
1334+
1335+ sbgen = atomic_read(&UNIONFS_SB(sb)->generation);
1336+ dgen = atomic_read(&UNIONFS_D(dentry)->generation);
1337+
1338+ if (unlikely(sbgen > dgen)) {
1339+ pr_debug("unionfs: retry dentry %s revalidation\n",
1340+ dentry->d_name.name);
1341+ schedule();
1342+ goto reval_dentry;
1343+ }
1344+ BUG_ON(sbgen > dgen);
1345+
1346+ err = __unionfs_file_revalidate(file, dentry, sb,
1347+ sbgen, dgen, willwrite);
1348+out:
1349+ return err;
1350+}
1351+
1352+/* same as unionfs_file_revalidate, but parent dentry must be locked too */
1353+int unionfs_file_revalidate_locked(struct file *file, bool willwrite)
1354+{
1355+ struct super_block *sb;
1356+ struct dentry *dentry;
1357+ int sbgen, dgen;
1358+ int err = 0, valid;
1359+
1360+ dentry = file->f_path.dentry;
1361+ sb = dentry->d_sb;
1362+ verify_locked(dentry);
1363+ verify_locked(dentry->d_parent);
1364+
1365+ /* first revalidate (locked) parent, then child */
1366+ valid = __unionfs_d_revalidate_chain(dentry->d_parent, NULL, false);
1367+ if (unlikely(!valid)) {
1368+ err = -ESTALE; /* same as what real_lookup does */
1369+ goto out;
1370+ }
1371+
1372+reval_dentry:
1373+ if (!d_deleted(dentry) &&
1374+ !__unionfs_d_revalidate_one_locked(dentry, NULL, willwrite)) {
1375+ err = -ESTALE;
1376+ goto out;
1377+ }
1378+
1379+ sbgen = atomic_read(&UNIONFS_SB(sb)->generation);
1380+ dgen = atomic_read(&UNIONFS_D(dentry)->generation);
1381+
1382+ if (unlikely(sbgen > dgen)) {
1383+ pr_debug("unionfs: retry (locked) dentry %s revalidation\n",
1384+ dentry->d_name.name);
1385+ schedule();
1386+ goto reval_dentry;
1387+ }
1388+ BUG_ON(sbgen > dgen);
1389+
1390+ err = __unionfs_file_revalidate(file, dentry, sb,
1391+ sbgen, dgen, willwrite);
1392+out:
1393+ return err;
1394+}
1395+
1396+/* unionfs_open helper function: open a directory */
1397+static int __open_dir(struct inode *inode, struct file *file)
1398+{
1399+ struct dentry *lower_dentry;
1400+ struct file *lower_file;
1401+ int bindex, bstart, bend;
1402+ struct vfsmount *mnt;
1403+
1404+ bstart = fbstart(file) = dbstart(file->f_path.dentry);
1405+ bend = fbend(file) = dbend(file->f_path.dentry);
1406+
1407+ for (bindex = bstart; bindex <= bend; bindex++) {
1408+ lower_dentry =
1409+ unionfs_lower_dentry_idx(file->f_path.dentry, bindex);
1410+ if (!lower_dentry)
1411+ continue;
1412+
1413+ dget(lower_dentry);
1414+ unionfs_mntget(file->f_path.dentry, bindex);
1415+ mnt = unionfs_lower_mnt_idx(file->f_path.dentry, bindex);
1416+ lower_file = dentry_open(lower_dentry, mnt, file->f_flags);
1417+ if (IS_ERR(lower_file))
1418+ return PTR_ERR(lower_file);
1419+
1420+ unionfs_set_lower_file_idx(file, bindex, lower_file);
1421+
1422+ /*
1423+ * The branchget goes after the open, because otherwise
1424+ * we would miss the reference on release.
1425+ */
1426+ branchget(inode->i_sb, bindex);
1427+ }
1428+
1429+ return 0;
1430+}
1431+
1432+/* unionfs_open helper function: open a file */
1433+static int __open_file(struct inode *inode, struct file *file)
1434+{
1435+ struct dentry *lower_dentry;
1436+ struct file *lower_file;
1437+ int lower_flags;
1438+ int bindex, bstart, bend;
1439+
1440+ lower_dentry = unionfs_lower_dentry(file->f_path.dentry);
1441+ lower_flags = file->f_flags;
1442+
1443+ bstart = fbstart(file) = dbstart(file->f_path.dentry);
1444+ bend = fbend(file) = dbend(file->f_path.dentry);
1445+
1446+ /*
1447+ * check for the permission for lower file. If the error is
1448+ * COPYUP_ERR, copyup the file.
1449+ */
1450+ if (lower_dentry->d_inode && is_robranch(file->f_path.dentry)) {
1451+ /*
1452+ * if the open will change the file, copy it up otherwise
1453+ * defer it.
1454+ */
1455+ if (lower_flags & O_TRUNC) {
1456+ int size = 0;
1457+ int err = -EROFS;
1458+
1459+ /* copyup the file */
1460+ for (bindex = bstart - 1; bindex >= 0; bindex--) {
1461+ err = copyup_file(
1462+ file->f_path.dentry->d_parent->d_inode,
1463+ file, bstart, bindex, size);
1464+ if (!err)
1465+ break;
1466+ }
1467+ return err;
1468+ } else {
1469+ /*
1470+ * turn off writeable flags, to force delayed copyup
1471+ * by caller.
1472+ */
1473+ lower_flags &= ~(OPEN_WRITE_FLAGS);
1474+ }
1475+ }
1476+
1477+ dget(lower_dentry);
1478+
1479+ /*
1480+ * dentry_open will decrement mnt refcnt if err.
1481+ * otherwise fput() will do an mntput() for us upon file close.
1482+ */
1483+ unionfs_mntget(file->f_path.dentry, bstart);
1484+ lower_file =
1485+ dentry_open(lower_dentry,
1486+ unionfs_lower_mnt_idx(file->f_path.dentry, bstart),
1487+ lower_flags);
1488+ if (IS_ERR(lower_file))
1489+ return PTR_ERR(lower_file);
1490+
1491+ unionfs_set_lower_file(file, lower_file);
1492+ branchget(inode->i_sb, bstart);
1493+
1494+ return 0;
1495+}
1496+
1497+int unionfs_open(struct inode *inode, struct file *file)
1498+{
1499+ int err = 0;
1500+ struct file *lower_file = NULL;
1501+ struct dentry *dentry = file->f_path.dentry;
1502+ int bindex = 0, bstart = 0, bend = 0;
1503+ int size;
1504+ int valid = 0;
1505+
1506+ unionfs_read_lock(inode->i_sb, UNIONFS_SMUTEX_PARENT);
1507+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
1508+ if (dentry != dentry->d_parent)
1509+ unionfs_lock_dentry(dentry->d_parent, UNIONFS_DMUTEX_PARENT);
1510+
1511+ valid = __unionfs_d_revalidate_chain(dentry->d_parent, NULL, false);
1512+ if (unlikely(!valid)) {
1513+ err = -ESTALE;
1514+ goto out_nofree;
1515+ }
1516+
1517+ file->private_data =
1518+ kzalloc(sizeof(struct unionfs_file_info), GFP_KERNEL);
1519+ if (unlikely(!UNIONFS_F(file))) {
1520+ err = -ENOMEM;
1521+ goto out_nofree;
1522+ }
1523+ fbstart(file) = -1;
1524+ fbend(file) = -1;
1525+ atomic_set(&UNIONFS_F(file)->generation,
1526+ atomic_read(&UNIONFS_I(inode)->generation));
1527+
1528+ size = sizeof(struct file *) * sbmax(inode->i_sb);
1529+ UNIONFS_F(file)->lower_files = kzalloc(size, GFP_KERNEL);
1530+ if (unlikely(!UNIONFS_F(file)->lower_files)) {
1531+ err = -ENOMEM;
1532+ goto out;
1533+ }
1534+ size = sizeof(int) * sbmax(inode->i_sb);
1535+ UNIONFS_F(file)->saved_branch_ids = kzalloc(size, GFP_KERNEL);
1536+ if (unlikely(!UNIONFS_F(file)->saved_branch_ids)) {
1537+ err = -ENOMEM;
1538+ goto out;
1539+ }
1540+
1541+ bstart = fbstart(file) = dbstart(dentry);
1542+ bend = fbend(file) = dbend(dentry);
1543+
1544+ /*
1545+ * open all directories and make the unionfs file struct point to
1546+ * these lower file structs
1547+ */
1548+ if (S_ISDIR(inode->i_mode))
1549+ err = __open_dir(inode, file); /* open a dir */
1550+ else
1551+ err = __open_file(inode, file); /* open a file */
1552+
1553+ /* freeing the allocated resources, and fput the opened files */
1554+ if (err) {
1555+ for (bindex = bstart; bindex <= bend; bindex++) {
1556+ lower_file = unionfs_lower_file_idx(file, bindex);
1557+ if (!lower_file)
1558+ continue;
1559+
1560+ branchput(dentry->d_sb, bindex);
1561+ /* fput calls dput for lower_dentry */
1562+ fput(lower_file);
1563+ }
1564+ }
1565+
1566+out:
1567+ if (err) {
1568+ kfree(UNIONFS_F(file)->lower_files);
1569+ kfree(UNIONFS_F(file)->saved_branch_ids);
1570+ kfree(UNIONFS_F(file));
1571+ }
1572+out_nofree:
1573+ if (!err) {
1574+ unionfs_postcopyup_setmnt(dentry);
1575+ unionfs_copy_attr_times(inode);
1576+ unionfs_check_file(file);
1577+ unionfs_check_inode(inode);
1578+ }
1579+ if (dentry != dentry->d_parent)
1580+ unionfs_unlock_dentry(dentry->d_parent);
1581+ unionfs_unlock_dentry(dentry);
1582+ unionfs_read_unlock(inode->i_sb);
1583+ return err;
1584+}
1585+
1586+/*
1587+ * release all lower object references & free the file info structure
1588+ *
1589+ * No need to grab sb info's rwsem.
1590+ */
1591+int unionfs_file_release(struct inode *inode, struct file *file)
1592+{
1593+ struct file *lower_file = NULL;
1594+ struct unionfs_file_info *fileinfo;
1595+ struct unionfs_inode_info *inodeinfo;
1596+ struct super_block *sb = inode->i_sb;
1597+ struct dentry *dentry = file->f_path.dentry;
1598+ int bindex, bstart, bend;
1599+ int fgen, err = 0;
1600+
1601+ unionfs_read_lock(sb, UNIONFS_SMUTEX_PARENT);
1602+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
1603+
1604+ /*
1605+ * Yes, we have to revalidate this file even if it's being released.
1606+ * This is important for open-but-unlinked files, as well as mmap
1607+ * support.
1608+ */
1609+ err = unionfs_file_revalidate(file, UNIONFS_F(file)->wrote_to_file);
1610+ if (unlikely(err))
1611+ goto out;
1612+ unionfs_check_file(file);
1613+ fileinfo = UNIONFS_F(file);
1614+ BUG_ON(file->f_path.dentry->d_inode != inode);
1615+ inodeinfo = UNIONFS_I(inode);
1616+
1617+ /* fput all the lower files */
1618+ fgen = atomic_read(&fileinfo->generation);
1619+ bstart = fbstart(file);
1620+ bend = fbend(file);
1621+
1622+ for (bindex = bstart; bindex <= bend; bindex++) {
1623+ lower_file = unionfs_lower_file_idx(file, bindex);
1624+
1625+ if (lower_file) {
1626+ unionfs_set_lower_file_idx(file, bindex, NULL);
1627+ fput(lower_file);
1628+ branchput(sb, bindex);
1629+ }
1630+
1631+ /* if there are no more refs to the dentry, dput it */
1632+ if (d_deleted(dentry)) {
1633+ dput(unionfs_lower_dentry_idx(dentry, bindex));
1634+ unionfs_set_lower_dentry_idx(dentry, bindex, NULL);
1635+ }
1636+ }
1637+
1638+ kfree(fileinfo->lower_files);
1639+ kfree(fileinfo->saved_branch_ids);
1640+
1641+ if (fileinfo->rdstate) {
1642+ fileinfo->rdstate->access = jiffies;
1643+ spin_lock(&inodeinfo->rdlock);
1644+ inodeinfo->rdcount++;
1645+ list_add_tail(&fileinfo->rdstate->cache,
1646+ &inodeinfo->readdircache);
1647+ mark_inode_dirty(inode);
1648+ spin_unlock(&inodeinfo->rdlock);
1649+ fileinfo->rdstate = NULL;
1650+ }
1651+ kfree(fileinfo);
1652+
1653+out:
1654+ unionfs_unlock_dentry(dentry);
1655+ unionfs_read_unlock(sb);
1656+ return err;
1657+}
1658+
1659+/* pass the ioctl to the lower fs */
1660+static long do_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
1661+{
1662+ struct file *lower_file;
1663+ int err;
1664+
1665+ lower_file = unionfs_lower_file(file);
1666+
1667+ err = -ENOTTY;
1668+ if (!lower_file || !lower_file->f_op)
1669+ goto out;
1670+ if (lower_file->f_op->unlocked_ioctl) {
1671+ err = lower_file->f_op->unlocked_ioctl(lower_file, cmd, arg);
1672+ } else if (lower_file->f_op->ioctl) {
1673+ lock_kernel();
1674+ err = lower_file->f_op->ioctl(
1675+ lower_file->f_path.dentry->d_inode,
1676+ lower_file, cmd, arg);
1677+ unlock_kernel();
1678+ }
1679+
1680+out:
1681+ return err;
1682+}
1683+
1684+/*
1685+ * return to user-space the branch indices containing the file in question
1686+ *
1687+ * We use fd_set and therefore we are limited to the number of the branches
1688+ * to FD_SETSIZE, which is currently 1024 - plenty for most people
1689+ */
1690+static int unionfs_ioctl_queryfile(struct file *file, unsigned int cmd,
1691+ unsigned long arg)
1692+{
1693+ int err = 0;
1694+ fd_set branchlist;
1695+ int bstart = 0, bend = 0, bindex = 0;
1696+ int orig_bstart, orig_bend;
1697+ struct dentry *dentry, *lower_dentry;
1698+ struct vfsmount *mnt;
1699+
1700+ dentry = file->f_path.dentry;
1701+ orig_bstart = dbstart(dentry);
1702+ orig_bend = dbend(dentry);
1703+ err = unionfs_partial_lookup(dentry);
1704+ if (err)
1705+ goto out;
1706+ bstart = dbstart(dentry);
1707+ bend = dbend(dentry);
1708+
1709+ FD_ZERO(&branchlist);
1710+
1711+ for (bindex = bstart; bindex <= bend; bindex++) {
1712+ lower_dentry = unionfs_lower_dentry_idx(dentry, bindex);
1713+ if (!lower_dentry)
1714+ continue;
1715+ if (likely(lower_dentry->d_inode))
1716+ FD_SET(bindex, &branchlist);
1717+ /* purge any lower objects after partial_lookup */
1718+ if (bindex < orig_bstart || bindex > orig_bend) {
1719+ dput(lower_dentry);
1720+ unionfs_set_lower_dentry_idx(dentry, bindex, NULL);
1721+ iput(unionfs_lower_inode_idx(dentry->d_inode, bindex));
1722+ unionfs_set_lower_inode_idx(dentry->d_inode, bindex,
1723+ NULL);
1724+ mnt = unionfs_lower_mnt_idx(dentry, bindex);
1725+ if (!mnt)
1726+ continue;
1727+ unionfs_mntput(dentry, bindex);
1728+ unionfs_set_lower_mnt_idx(dentry, bindex, NULL);
1729+ }
1730+ }
1731+ /* restore original dentry's offsets */
1732+ dbstart(dentry) = orig_bstart;
1733+ dbend(dentry) = orig_bend;
1734+ ibstart(dentry->d_inode) = orig_bstart;
1735+ ibend(dentry->d_inode) = orig_bend;
1736+
1737+ err = copy_to_user((void __user *)arg, &branchlist, sizeof(fd_set));
1738+ if (unlikely(err))
1739+ err = -EFAULT;
1740+
1741+out:
1742+ return err < 0 ? err : bend;
1743+}
1744+
1745+long unionfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
1746+{
1747+ long err;
1748+ struct dentry *dentry = file->f_path.dentry;
1749+
1750+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_PARENT);
1751+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
1752+
1753+ err = unionfs_file_revalidate(file, true);
1754+ if (unlikely(err))
1755+ goto out;
1756+
1757+ /* check if asked for local commands */
1758+ switch (cmd) {
1759+ case UNIONFS_IOCTL_INCGEN:
1760+ /* Increment the superblock generation count */
1761+ pr_info("unionfs: incgen ioctl deprecated; "
1762+ "use \"-o remount,incgen\"\n");
1763+ err = -ENOSYS;
1764+ break;
1765+
1766+ case UNIONFS_IOCTL_QUERYFILE:
1767+ /* Return list of branches containing the given file */
1768+ err = unionfs_ioctl_queryfile(file, cmd, arg);
1769+ break;
1770+
1771+ default:
1772+ /* pass the ioctl down */
1773+ err = do_ioctl(file, cmd, arg);
1774+ break;
1775+ }
1776+
1777+out:
1778+ unionfs_check_file(file);
1779+ unionfs_unlock_dentry(dentry);
1780+ unionfs_read_unlock(dentry->d_sb);
1781+ return err;
1782+}
1783+
1784+int unionfs_flush(struct file *file, fl_owner_t id)
1785+{
1786+ int err = 0;
1787+ struct file *lower_file = NULL;
1788+ struct dentry *dentry = file->f_path.dentry;
1789+ int bindex, bstart, bend;
1790+
1791+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_PARENT);
1792+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
1793+
1794+ err = unionfs_file_revalidate(file, UNIONFS_F(file)->wrote_to_file);
1795+ if (unlikely(err))
1796+ goto out;
1797+ unionfs_check_file(file);
1798+
1799+ bstart = fbstart(file);
1800+ bend = fbend(file);
1801+ for (bindex = bstart; bindex <= bend; bindex++) {
1802+ lower_file = unionfs_lower_file_idx(file, bindex);
1803+
1804+ if (lower_file && lower_file->f_op &&
1805+ lower_file->f_op->flush) {
1806+ err = lower_file->f_op->flush(lower_file, id);
1807+ if (err)
1808+ goto out;
1809+ }
1810+
1811+ }
1812+
1813+out:
1814+ if (!err)
1815+ unionfs_check_file(file);
1816+ unionfs_unlock_dentry(dentry);
1817+ unionfs_read_unlock(dentry->d_sb);
1818+ return err;
1819+}
1820diff --git a/fs/unionfs/copyup.c b/fs/unionfs/copyup.c
1821new file mode 100644
1822index 0000000..ae6ea2b
1823--- /dev/null
1824+++ b/fs/unionfs/copyup.c
1825@@ -0,0 +1,879 @@
1826+/*
1827+ * Copyright (c) 2003-2008 Erez Zadok
1828+ * Copyright (c) 2003-2006 Charles P. Wright
1829+ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
1830+ * Copyright (c) 2005-2006 Junjiro Okajima
1831+ * Copyright (c) 2005 Arun M. Krishnakumar
1832+ * Copyright (c) 2004-2006 David P. Quigley
1833+ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
1834+ * Copyright (c) 2003 Puja Gupta
1835+ * Copyright (c) 2003 Harikesavan Krishnan
1836+ * Copyright (c) 2003-2008 Stony Brook University
1837+ * Copyright (c) 2003-2008 The Research Foundation of SUNY
1838+ *
1839+ * This program is free software; you can redistribute it and/or modify
1840+ * it under the terms of the GNU General Public License version 2 as
1841+ * published by the Free Software Foundation.
1842+ */
1843+
1844+#include "union.h"
1845+
1846+/*
1847+ * For detailed explanation of copyup see:
1848+ * Documentation/filesystems/unionfs/concepts.txt
1849+ */
1850+
1851+#ifdef CONFIG_UNION_FS_XATTR
1852+/* copyup all extended attrs for a given dentry */
1853+static int copyup_xattrs(struct dentry *old_lower_dentry,
1854+ struct dentry *new_lower_dentry)
1855+{
1856+ int err = 0;
1857+ ssize_t list_size = -1;
1858+ char *name_list = NULL;
1859+ char *attr_value = NULL;
1860+ char *name_list_buf = NULL;
1861+
1862+ /* query the actual size of the xattr list */
1863+ list_size = vfs_listxattr(old_lower_dentry, NULL, 0);
1864+ if (list_size <= 0) {
1865+ err = list_size;
1866+ goto out;
1867+ }
1868+
1869+ /* allocate space for the actual list */
1870+ name_list = unionfs_xattr_alloc(list_size + 1, XATTR_LIST_MAX);
1871+ if (unlikely(!name_list || IS_ERR(name_list))) {
1872+ err = PTR_ERR(name_list);
1873+ goto out;
1874+ }
1875+
1876+ name_list_buf = name_list; /* save for kfree at end */
1877+
1878+ /* now get the actual xattr list of the source file */
1879+ list_size = vfs_listxattr(old_lower_dentry, name_list, list_size);
1880+ if (list_size <= 0) {
1881+ err = list_size;
1882+ goto out;
1883+ }
1884+
1885+ /* allocate space to hold each xattr's value */
1886+ attr_value = unionfs_xattr_alloc(XATTR_SIZE_MAX, XATTR_SIZE_MAX);
1887+ if (unlikely(!attr_value || IS_ERR(attr_value))) {
1888+ err = PTR_ERR(name_list);
1889+ goto out;
1890+ }
1891+
1892+ /* in a loop, get and set each xattr from src to dst file */
1893+ while (*name_list) {
1894+ ssize_t size;
1895+
1896+ /* Lock here since vfs_getxattr doesn't lock for us */
1897+ mutex_lock(&old_lower_dentry->d_inode->i_mutex);
1898+ size = vfs_getxattr(old_lower_dentry, name_list,
1899+ attr_value, XATTR_SIZE_MAX);
1900+ mutex_unlock(&old_lower_dentry->d_inode->i_mutex);
1901+ if (size < 0) {
1902+ err = size;
1903+ goto out;
1904+ }
1905+ if (size > XATTR_SIZE_MAX) {
1906+ err = -E2BIG;
1907+ goto out;
1908+ }
1909+ /* Don't lock here since vfs_setxattr does it for us. */
1910+ err = vfs_setxattr(new_lower_dentry, name_list, attr_value,
1911+ size, 0);
1912+ /*
1913+ * Selinux depends on "security.*" xattrs, so to maintain
1914+ * the security of copied-up files, if Selinux is active,
1915+ * then we must copy these xattrs as well. So we need to
1916+ * temporarily get FOWNER privileges.
1917+ * XXX: move entire copyup code to SIOQ.
1918+ */
1919+ if (err == -EPERM && !capable(CAP_FOWNER)) {
1920+ cap_raise(current->cap_effective, CAP_FOWNER);
1921+ err = vfs_setxattr(new_lower_dentry, name_list,
1922+ attr_value, size, 0);
1923+ cap_lower(current->cap_effective, CAP_FOWNER);
1924+ }
1925+ if (err < 0)
1926+ goto out;
1927+ name_list += strlen(name_list) + 1;
1928+ }
1929+out:
1930+ unionfs_xattr_kfree(name_list_buf);
1931+ unionfs_xattr_kfree(attr_value);
1932+ /* Ignore if xattr isn't supported */
1933+ if (err == -ENOTSUPP || err == -EOPNOTSUPP)
1934+ err = 0;
1935+ return err;
1936+}
1937+#endif /* CONFIG_UNION_FS_XATTR */
1938+
1939+/*
1940+ * Determine the mode based on the copyup flags, and the existing dentry.
1941+ *
1942+ * Handle file systems which may not support certain options. For example
1943+ * jffs2 doesn't allow one to chmod a symlink. So we ignore such harmless
1944+ * errors, rather than propagating them up, which results in copyup errors
1945+ * and errors returned back to users.
1946+ */
1947+static int copyup_permissions(struct super_block *sb,
1948+ struct dentry *old_lower_dentry,
1949+ struct dentry *new_lower_dentry)
1950+{
1951+ struct inode *i = old_lower_dentry->d_inode;
1952+ struct iattr newattrs;
1953+ int err;
1954+
1955+ newattrs.ia_atime = i->i_atime;
1956+ newattrs.ia_mtime = i->i_mtime;
1957+ newattrs.ia_ctime = i->i_ctime;
1958+ newattrs.ia_gid = i->i_gid;
1959+ newattrs.ia_uid = i->i_uid;
1960+ newattrs.ia_valid = ATTR_CTIME | ATTR_ATIME | ATTR_MTIME |
1961+ ATTR_ATIME_SET | ATTR_MTIME_SET | ATTR_FORCE |
1962+ ATTR_GID | ATTR_UID;
1963+ mutex_lock(&new_lower_dentry->d_inode->i_mutex);
1964+ err = notify_change(new_lower_dentry, &newattrs);
1965+ if (err)
1966+ goto out;
1967+
1968+ /* now try to change the mode and ignore EOPNOTSUPP on symlinks */
1969+ newattrs.ia_mode = i->i_mode;
1970+ newattrs.ia_valid = ATTR_MODE | ATTR_FORCE;
1971+ err = notify_change(new_lower_dentry, &newattrs);
1972+ if (err == -EOPNOTSUPP &&
1973+ S_ISLNK(new_lower_dentry->d_inode->i_mode)) {
1974+ printk(KERN_WARNING
1975+ "unionfs: changing \"%s\" symlink mode unsupported\n",
1976+ new_lower_dentry->d_name.name);
1977+ err = 0;
1978+ }
1979+
1980+out:
1981+ mutex_unlock(&new_lower_dentry->d_inode->i_mutex);
1982+ return err;
1983+}
1984+
1985+/*
1986+ * create the new device/file/directory - use copyup_permission to copyup
1987+ * times, and mode
1988+ *
1989+ * if the object being copied up is a regular file, the file is only created,
1990+ * the contents have to be copied up separately
1991+ */
1992+static int __copyup_ndentry(struct dentry *old_lower_dentry,
1993+ struct dentry *new_lower_dentry,
1994+ struct dentry *new_lower_parent_dentry,
1995+ char *symbuf)
1996+{
1997+ int err = 0;
1998+ umode_t old_mode = old_lower_dentry->d_inode->i_mode;
1999+ struct sioq_args args;
2000+
2001+ if (S_ISDIR(old_mode)) {
2002+ args.mkdir.parent = new_lower_parent_dentry->d_inode;
2003+ args.mkdir.dentry = new_lower_dentry;
2004+ args.mkdir.mode = old_mode;
2005+
2006+ run_sioq(__unionfs_mkdir, &args);
2007+ err = args.err;
2008+ } else if (S_ISLNK(old_mode)) {
2009+ args.symlink.parent = new_lower_parent_dentry->d_inode;
2010+ args.symlink.dentry = new_lower_dentry;
2011+ args.symlink.symbuf = symbuf;
2012+
2013+ run_sioq(__unionfs_symlink, &args);
2014+ err = args.err;
2015+ } else if (S_ISBLK(old_mode) || S_ISCHR(old_mode) ||
2016+ S_ISFIFO(old_mode) || S_ISSOCK(old_mode)) {
2017+ args.mknod.parent = new_lower_parent_dentry->d_inode;
2018+ args.mknod.dentry = new_lower_dentry;
2019+ args.mknod.mode = old_mode;
2020+ args.mknod.dev = old_lower_dentry->d_inode->i_rdev;
2021+
2022+ run_sioq(__unionfs_mknod, &args);
2023+ err = args.err;
2024+ } else if (S_ISREG(old_mode)) {
2025+ struct nameidata nd;
2026+ err = init_lower_nd(&nd, LOOKUP_CREATE);
2027+ if (unlikely(err < 0))
2028+ goto out;
2029+ args.create.nd = &nd;
2030+ args.create.parent = new_lower_parent_dentry->d_inode;
2031+ args.create.dentry = new_lower_dentry;
2032+ args.create.mode = old_mode;
2033+
2034+ run_sioq(__unionfs_create, &args);
2035+ err = args.err;
2036+ release_lower_nd(&nd, err);
2037+ } else {
2038+ printk(KERN_CRIT "unionfs: unknown inode type %d\n",
2039+ old_mode);
2040+ BUG();
2041+ }
2042+
2043+out:
2044+ return err;
2045+}
2046+
2047+static int __copyup_reg_data(struct dentry *dentry,
2048+ struct dentry *new_lower_dentry, int new_bindex,
2049+ struct dentry *old_lower_dentry, int old_bindex,
2050+ struct file **copyup_file, loff_t len)
2051+{
2052+ struct super_block *sb = dentry->d_sb;
2053+ struct file *input_file;
2054+ struct file *output_file;
2055+ struct vfsmount *output_mnt;
2056+ mm_segment_t old_fs;
2057+ char *buf = NULL;
2058+ ssize_t read_bytes, write_bytes;
2059+ loff_t size;
2060+ int err = 0;
2061+
2062+ /* open old file */
2063+ unionfs_mntget(dentry, old_bindex);
2064+ branchget(sb, old_bindex);
2065+ /* dentry_open calls dput and mntput if it returns an error */
2066+ input_file = dentry_open(old_lower_dentry,
2067+ unionfs_lower_mnt_idx(dentry, old_bindex),
2068+ O_RDONLY | O_LARGEFILE);
2069+ if (IS_ERR(input_file)) {
2070+ dput(old_lower_dentry);
2071+ err = PTR_ERR(input_file);
2072+ goto out;
2073+ }
2074+ if (unlikely(!input_file->f_op || !input_file->f_op->read)) {
2075+ err = -EINVAL;
2076+ goto out_close_in;
2077+ }
2078+
2079+ /* open new file */
2080+ dget(new_lower_dentry);
2081+ output_mnt = unionfs_mntget(sb->s_root, new_bindex);
2082+ branchget(sb, new_bindex);
2083+ output_file = dentry_open(new_lower_dentry, output_mnt,
2084+ O_RDWR | O_LARGEFILE);
2085+ if (IS_ERR(output_file)) {
2086+ err = PTR_ERR(output_file);
2087+ goto out_close_in2;
2088+ }
2089+ if (unlikely(!output_file->f_op || !output_file->f_op->write)) {
2090+ err = -EINVAL;
2091+ goto out_close_out;
2092+ }
2093+
2094+ /* allocating a buffer */
2095+ buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
2096+ if (unlikely(!buf)) {
2097+ err = -ENOMEM;
2098+ goto out_close_out;
2099+ }
2100+
2101+ input_file->f_pos = 0;
2102+ output_file->f_pos = 0;
2103+
2104+ old_fs = get_fs();
2105+ set_fs(KERNEL_DS);
2106+
2107+ size = len;
2108+ err = 0;
2109+ do {
2110+ if (len >= PAGE_SIZE)
2111+ size = PAGE_SIZE;
2112+ else if ((len < PAGE_SIZE) && (len > 0))
2113+ size = len;
2114+
2115+ len -= PAGE_SIZE;
2116+
2117+ read_bytes =
2118+ input_file->f_op->read(input_file,
2119+ (char __user *)buf, size,
2120+ &input_file->f_pos);
2121+ if (read_bytes <= 0) {
2122+ err = read_bytes;
2123+ break;
2124+ }
2125+
2126+ /* see Documentation/filesystems/unionfs/issues.txt */
2127+ lockdep_off();
2128+ write_bytes =
2129+ output_file->f_op->write(output_file,
2130+ (char __user *)buf,
2131+ read_bytes,
2132+ &output_file->f_pos);
2133+ lockdep_on();
2134+ if ((write_bytes < 0) || (write_bytes < read_bytes)) {
2135+ err = write_bytes;
2136+ break;
2137+ }
2138+ } while ((read_bytes > 0) && (len > 0));
2139+
2140+ set_fs(old_fs);
2141+
2142+ kfree(buf);
2143+
2144+ if (!err)
2145+ err = output_file->f_op->fsync(output_file,
2146+ new_lower_dentry, 0);
2147+
2148+ if (err)
2149+ goto out_close_out;
2150+
2151+ if (copyup_file) {
2152+ *copyup_file = output_file;
2153+ goto out_close_in;
2154+ }
2155+
2156+out_close_out:
2157+ fput(output_file);
2158+
2159+out_close_in2:
2160+ branchput(sb, new_bindex);
2161+
2162+out_close_in:
2163+ fput(input_file);
2164+
2165+out:
2166+ branchput(sb, old_bindex);
2167+
2168+ return err;
2169+}
2170+
2171+/*
2172+ * dput the lower references for old and new dentry & clear a lower dentry
2173+ * pointer
2174+ */
2175+static void __clear(struct dentry *dentry, struct dentry *old_lower_dentry,
2176+ int old_bstart, int old_bend,
2177+ struct dentry *new_lower_dentry, int new_bindex)
2178+{
2179+ /* get rid of the lower dentry and all its traces */
2180+ unionfs_set_lower_dentry_idx(dentry, new_bindex, NULL);
2181+ dbstart(dentry) = old_bstart;
2182+ dbend(dentry) = old_bend;
2183+
2184+ dput(new_lower_dentry);
2185+ dput(old_lower_dentry);
2186+}
2187+
2188+/*
2189+ * Copy up a dentry to a file of specified name.
2190+ *
2191+ * @dir: used to pull the ->i_sb to access other branches
2192+ * @dentry: the non-negative dentry whose lower_inode we should copy
2193+ * @bstart: the branch of the lower_inode to copy from
2194+ * @new_bindex: the branch to create the new file in
2195+ * @name: the name of the file to create
2196+ * @namelen: length of @name
2197+ * @copyup_file: the "struct file" to return (optional)
2198+ * @len: how many bytes to copy-up?
2199+ */
2200+int copyup_dentry(struct inode *dir, struct dentry *dentry, int bstart,
2201+ int new_bindex, const char *name, int namelen,
2202+ struct file **copyup_file, loff_t len)
2203+{
2204+ struct dentry *new_lower_dentry;
2205+ struct dentry *old_lower_dentry = NULL;
2206+ struct super_block *sb;
2207+ int err = 0;
2208+ int old_bindex;
2209+ int old_bstart;
2210+ int old_bend;
2211+ struct dentry *new_lower_parent_dentry = NULL;
2212+ mm_segment_t oldfs;
2213+ char *symbuf = NULL;
2214+
2215+ verify_locked(dentry);
2216+
2217+ old_bindex = bstart;
2218+ old_bstart = dbstart(dentry);
2219+ old_bend = dbend(dentry);
2220+
2221+ BUG_ON(new_bindex < 0);
2222+ BUG_ON(new_bindex >= old_bindex);
2223+
2224+ sb = dir->i_sb;
2225+
2226+ err = is_robranch_super(sb, new_bindex);
2227+ if (err)
2228+ goto out;
2229+
2230+ /* Create the directory structure above this dentry. */
2231+ new_lower_dentry = create_parents(dir, dentry, name, new_bindex);
2232+ if (IS_ERR(new_lower_dentry)) {
2233+ err = PTR_ERR(new_lower_dentry);
2234+ goto out;
2235+ }
2236+
2237+ old_lower_dentry = unionfs_lower_dentry_idx(dentry, old_bindex);
2238+ /* we conditionally dput this old_lower_dentry at end of function */
2239+ dget(old_lower_dentry);
2240+
2241+ /* For symlinks, we must read the link before we lock the directory. */
2242+ if (S_ISLNK(old_lower_dentry->d_inode->i_mode)) {
2243+
2244+ symbuf = kmalloc(PATH_MAX, GFP_KERNEL);
2245+ if (unlikely(!symbuf)) {
2246+ __clear(dentry, old_lower_dentry,
2247+ old_bstart, old_bend,
2248+ new_lower_dentry, new_bindex);
2249+ err = -ENOMEM;
2250+ goto out_free;
2251+ }
2252+
2253+ oldfs = get_fs();
2254+ set_fs(KERNEL_DS);
2255+ err = old_lower_dentry->d_inode->i_op->readlink(
2256+ old_lower_dentry,
2257+ (char __user *)symbuf,
2258+ PATH_MAX);
2259+ set_fs(oldfs);
2260+ if (err < 0) {
2261+ __clear(dentry, old_lower_dentry,
2262+ old_bstart, old_bend,
2263+ new_lower_dentry, new_bindex);
2264+ goto out_free;
2265+ }
2266+ symbuf[err] = '\0';
2267+ }
2268+
2269+ /* Now we lock the parent, and create the object in the new branch. */
2270+ new_lower_parent_dentry = lock_parent(new_lower_dentry);
2271+
2272+ /* create the new inode */
2273+ err = __copyup_ndentry(old_lower_dentry, new_lower_dentry,
2274+ new_lower_parent_dentry, symbuf);
2275+
2276+ if (err) {
2277+ __clear(dentry, old_lower_dentry,
2278+ old_bstart, old_bend,
2279+ new_lower_dentry, new_bindex);
2280+ goto out_unlock;
2281+ }
2282+
2283+ /* We actually copyup the file here. */
2284+ if (S_ISREG(old_lower_dentry->d_inode->i_mode))
2285+ err = __copyup_reg_data(dentry, new_lower_dentry, new_bindex,
2286+ old_lower_dentry, old_bindex,
2287+ copyup_file, len);
2288+ if (err)
2289+ goto out_unlink;
2290+
2291+ /* Set permissions. */
2292+ err = copyup_permissions(sb, old_lower_dentry, new_lower_dentry);
2293+ if (err)
2294+ goto out_unlink;
2295+
2296+#ifdef CONFIG_UNION_FS_XATTR
2297+ /* Selinux uses extended attributes for permissions. */
2298+ err = copyup_xattrs(old_lower_dentry, new_lower_dentry);
2299+ if (err)
2300+ goto out_unlink;
2301+#endif /* CONFIG_UNION_FS_XATTR */
2302+
2303+ /* do not allow files getting deleted to be re-interposed */
2304+ if (!d_deleted(dentry))
2305+ unionfs_reinterpose(dentry);
2306+
2307+ goto out_unlock;
2308+
2309+out_unlink:
2310+ /*
2311+ * copyup failed, because we possibly ran out of space or
2312+ * quota, or something else happened so let's unlink; we don't
2313+ * really care about the return value of vfs_unlink
2314+ */
2315+ vfs_unlink(new_lower_parent_dentry->d_inode, new_lower_dentry);
2316+
2317+ if (copyup_file) {
2318+ /* need to close the file */
2319+
2320+ fput(*copyup_file);
2321+ branchput(sb, new_bindex);
2322+ }
2323+
2324+ /*
2325+ * TODO: should we reset the error to something like -EIO?
2326+ *
2327+ * If we don't reset, the user may get some nonsensical errors, but
2328+ * on the other hand, if we reset to EIO, we guarantee that the user
2329+ * will get a "confusing" error message.
2330+ */
2331+
2332+out_unlock:
2333+ unlock_dir(new_lower_parent_dentry);
2334+
2335+out_free:
2336+ /*
2337+ * If old_lower_dentry was not a file, then we need to dput it. If
2338+ * it was a file, then it was already dput indirectly by other
2339+ * functions we call above which operate on regular files.
2340+ */
2341+ if (old_lower_dentry && old_lower_dentry->d_inode &&
2342+ !S_ISREG(old_lower_dentry->d_inode->i_mode))
2343+ dput(old_lower_dentry);
2344+ kfree(symbuf);
2345+
2346+ if (err)
2347+ goto out;
2348+ if (!S_ISDIR(dentry->d_inode->i_mode)) {
2349+ unionfs_postcopyup_release(dentry);
2350+ if (!unionfs_lower_inode(dentry->d_inode)) {
2351+ /*
2352+ * If we got here, then we copied up to an
2353+ * unlinked-open file, whose name is .unionfsXXXXX.
2354+ */
2355+ struct inode *inode = new_lower_dentry->d_inode;
2356+ atomic_inc(&inode->i_count);
2357+ unionfs_set_lower_inode_idx(dentry->d_inode,
2358+ ibstart(dentry->d_inode),
2359+ inode);
2360+ }
2361+ }
2362+ unionfs_postcopyup_setmnt(dentry);
2363+ /* sync inode times from copied-up inode to our inode */
2364+ unionfs_copy_attr_times(dentry->d_inode);
2365+ unionfs_check_inode(dir);
2366+ unionfs_check_dentry(dentry);
2367+out:
2368+ return err;
2369+}
2370+
2371+/*
2372+ * This function creates a copy of a file represented by 'file' which
2373+ * currently resides in branch 'bstart' to branch 'new_bindex.' The copy
2374+ * will be named "name".
2375+ */
2376+int copyup_named_file(struct inode *dir, struct file *file, char *name,
2377+ int bstart, int new_bindex, loff_t len)
2378+{
2379+ int err = 0;
2380+ struct file *output_file = NULL;
2381+
2382+ err = copyup_dentry(dir, file->f_path.dentry, bstart, new_bindex,
2383+ name, strlen(name), &output_file, len);
2384+ if (!err) {
2385+ fbstart(file) = new_bindex;
2386+ unionfs_set_lower_file_idx(file, new_bindex, output_file);
2387+ }
2388+
2389+ return err;
2390+}
2391+
2392+/*
2393+ * This function creates a copy of a file represented by 'file' which
2394+ * currently resides in branch 'bstart' to branch 'new_bindex'.
2395+ */
2396+int copyup_file(struct inode *dir, struct file *file, int bstart,
2397+ int new_bindex, loff_t len)
2398+{
2399+ int err = 0;
2400+ struct file *output_file = NULL;
2401+ struct dentry *dentry = file->f_path.dentry;
2402+
2403+ err = copyup_dentry(dir, dentry, bstart, new_bindex,
2404+ dentry->d_name.name, dentry->d_name.len,
2405+ &output_file, len);
2406+ if (!err) {
2407+ fbstart(file) = new_bindex;
2408+ unionfs_set_lower_file_idx(file, new_bindex, output_file);
2409+ }
2410+
2411+ return err;
2412+}
2413+
2414+/* purge a dentry's lower-branch states (dput/mntput, etc.) */
2415+static void __cleanup_dentry(struct dentry *dentry, int bindex,
2416+ int old_bstart, int old_bend)
2417+{
2418+ int loop_start;
2419+ int loop_end;
2420+ int new_bstart = -1;
2421+ int new_bend = -1;
2422+ int i;
2423+
2424+ loop_start = min(old_bstart, bindex);
2425+ loop_end = max(old_bend, bindex);
2426+
2427+ /*
2428+ * This loop sets the bstart and bend for the new dentry by
2429+ * traversing from left to right. It also dputs all negative
2430+ * dentries except bindex
2431+ */
2432+ for (i = loop_start; i <= loop_end; i++) {
2433+ if (!unionfs_lower_dentry_idx(dentry, i))
2434+ continue;
2435+
2436+ if (i == bindex) {
2437+ new_bend = i;
2438+ if (new_bstart < 0)
2439+ new_bstart = i;
2440+ continue;
2441+ }
2442+
2443+ if (!unionfs_lower_dentry_idx(dentry, i)->d_inode) {
2444+ dput(unionfs_lower_dentry_idx(dentry, i));
2445+ unionfs_set_lower_dentry_idx(dentry, i, NULL);
2446+
2447+ unionfs_mntput(dentry, i);
2448+ unionfs_set_lower_mnt_idx(dentry, i, NULL);
2449+ } else {
2450+ if (new_bstart < 0)
2451+ new_bstart = i;
2452+ new_bend = i;
2453+ }
2454+ }
2455+
2456+ if (new_bstart < 0)
2457+ new_bstart = bindex;
2458+ if (new_bend < 0)
2459+ new_bend = bindex;
2460+ dbstart(dentry) = new_bstart;
2461+ dbend(dentry) = new_bend;
2462+
2463+}
2464+
2465+/* set lower inode ptr and update bstart & bend if necessary */
2466+static void __set_inode(struct dentry *upper, struct dentry *lower,
2467+ int bindex)
2468+{
2469+ unionfs_set_lower_inode_idx(upper->d_inode, bindex,
2470+ igrab(lower->d_inode));
2471+ if (likely(ibstart(upper->d_inode) > bindex))
2472+ ibstart(upper->d_inode) = bindex;
2473+ if (likely(ibend(upper->d_inode) < bindex))
2474+ ibend(upper->d_inode) = bindex;
2475+
2476+}
2477+
2478+/* set lower dentry ptr and update bstart & bend if necessary */
2479+static void __set_dentry(struct dentry *upper, struct dentry *lower,
2480+ int bindex)
2481+{
2482+ unionfs_set_lower_dentry_idx(upper, bindex, lower);
2483+ if (likely(dbstart(upper) > bindex))
2484+ dbstart(upper) = bindex;
2485+ if (likely(dbend(upper) < bindex))
2486+ dbend(upper) = bindex;
2487+}
2488+
2489+/*
2490+ * This function replicates the directory structure up-to given dentry
2491+ * in the bindex branch.
2492+ */
2493+struct dentry *create_parents(struct inode *dir, struct dentry *dentry,
2494+ const char *name, int bindex)
2495+{
2496+ int err;
2497+ struct dentry *child_dentry;
2498+ struct dentry *parent_dentry;
2499+ struct dentry *lower_parent_dentry = NULL;
2500+ struct dentry *lower_dentry = NULL;
2501+ const char *childname;
2502+ unsigned int childnamelen;
2503+ int nr_dentry;
2504+ int count = 0;
2505+ int old_bstart;
2506+ int old_bend;
2507+ struct dentry **path = NULL;
2508+ struct super_block *sb;
2509+
2510+ verify_locked(dentry);
2511+
2512+ err = is_robranch_super(dir->i_sb, bindex);
2513+ if (err) {
2514+ lower_dentry = ERR_PTR(err);
2515+ goto out;
2516+ }
2517+
2518+ old_bstart = dbstart(dentry);
2519+ old_bend = dbend(dentry);
2520+
2521+ lower_dentry = ERR_PTR(-ENOMEM);
2522+
2523+ /* There is no sense allocating any less than the minimum. */
2524+ nr_dentry = 1;
2525+ path = kmalloc(nr_dentry * sizeof(struct dentry *), GFP_KERNEL);
2526+ if (unlikely(!path))
2527+ goto out;
2528+
2529+ /* assume the negative dentry of unionfs as the parent dentry */
2530+ parent_dentry = dentry;
2531+
2532+ /*
2533+ * This loop finds the first parent that exists in the given branch.
2534+ * We start building the directory structure from there. At the end
2535+ * of the loop, the following should hold:
2536+ * - child_dentry is the first nonexistent child
2537+ * - parent_dentry is the first existent parent
2538+ * - path[0] is the = deepest child
2539+ * - path[count] is the first child to create
2540+ */
2541+ do {
2542+ child_dentry = parent_dentry;
2543+
2544+ /* find the parent directory dentry in unionfs */
2545+ parent_dentry = dget_parent(child_dentry);
2546+
2547+ /* find out the lower_parent_dentry in the given branch */
2548+ lower_parent_dentry =
2549+ unionfs_lower_dentry_idx(parent_dentry, bindex);
2550+
2551+ /* grow path table */
2552+ if (count == nr_dentry) {
2553+ void *p;
2554+
2555+ nr_dentry *= 2;
2556+ p = krealloc(path, nr_dentry * sizeof(struct dentry *),
2557+ GFP_KERNEL);
2558+ if (unlikely(!p)) {
2559+ lower_dentry = ERR_PTR(-ENOMEM);
2560+ goto out;
2561+ }
2562+ path = p;
2563+ }
2564+
2565+ /* store the child dentry */
2566+ path[count++] = child_dentry;
2567+ } while (!lower_parent_dentry);
2568+ count--;
2569+
2570+ sb = dentry->d_sb;
2571+
2572+ /*
2573+ * This code goes between the begin/end labels and basically
2574+ * emulates a while(child_dentry != dentry), only cleaner and
2575+ * shorter than what would be a much longer while loop.
2576+ */
2577+begin:
2578+ /* get lower parent dir in the current branch */
2579+ lower_parent_dentry = unionfs_lower_dentry_idx(parent_dentry, bindex);
2580+ dput(parent_dentry);
2581+
2582+ /* init the values to lookup */
2583+ childname = child_dentry->d_name.name;
2584+ childnamelen = child_dentry->d_name.len;
2585+
2586+ if (child_dentry != dentry) {
2587+ /* lookup child in the underlying file system */
2588+ lower_dentry = lookup_one_len(childname, lower_parent_dentry,
2589+ childnamelen);
2590+ if (IS_ERR(lower_dentry))
2591+ goto out;
2592+ } else {
2593+ /*
2594+ * Is the name a whiteout of the child name ? lookup the
2595+ * whiteout child in the underlying file system
2596+ */
2597+ lower_dentry = lookup_one_len(name, lower_parent_dentry,
2598+ strlen(name));
2599+ if (IS_ERR(lower_dentry))
2600+ goto out;
2601+
2602+ /* Replace the current dentry (if any) with the new one */
2603+ dput(unionfs_lower_dentry_idx(dentry, bindex));
2604+ unionfs_set_lower_dentry_idx(dentry, bindex,
2605+ lower_dentry);
2606+
2607+ __cleanup_dentry(dentry, bindex, old_bstart, old_bend);
2608+ goto out;
2609+ }
2610+
2611+ if (lower_dentry->d_inode) {
2612+ /*
2613+ * since this already exists we dput to avoid
2614+ * multiple references on the same dentry
2615+ */
2616+ dput(lower_dentry);
2617+ } else {
2618+ struct sioq_args args;
2619+
2620+ /* it's a negative dentry, create a new dir */
2621+ lower_parent_dentry = lock_parent(lower_dentry);
2622+
2623+ args.mkdir.parent = lower_parent_dentry->d_inode;
2624+ args.mkdir.dentry = lower_dentry;
2625+ args.mkdir.mode = child_dentry->d_inode->i_mode;
2626+
2627+ run_sioq(__unionfs_mkdir, &args);
2628+ err = args.err;
2629+
2630+ if (!err)
2631+ err = copyup_permissions(dir->i_sb, child_dentry,
2632+ lower_dentry);
2633+ unlock_dir(lower_parent_dentry);
2634+ if (err) {
2635+ dput(lower_dentry);
2636+ lower_dentry = ERR_PTR(err);
2637+ goto out;
2638+ }
2639+
2640+ }
2641+
2642+ __set_inode(child_dentry, lower_dentry, bindex);
2643+ __set_dentry(child_dentry, lower_dentry, bindex);
2644+ /*
2645+ * update times of this dentry, but also the parent, because if
2646+ * we changed, the parent may have changed too.
2647+ */
2648+ fsstack_copy_attr_times(parent_dentry->d_inode,
2649+ lower_parent_dentry->d_inode);
2650+ unionfs_copy_attr_times(child_dentry->d_inode);
2651+
2652+ parent_dentry = child_dentry;
2653+ child_dentry = path[--count];
2654+ goto begin;
2655+out:
2656+ /* cleanup any leftover locks from the do/while loop above */
2657+ if (IS_ERR(lower_dentry))
2658+ while (count)
2659+ dput(path[count--]);
2660+ kfree(path);
2661+ return lower_dentry;
2662+}
2663+
2664+/*
2665+ * Post-copyup helper to ensure we have valid mnts: set lower mnt of
2666+ * dentry+parents to the first parent node that has an mnt.
2667+ */
2668+void unionfs_postcopyup_setmnt(struct dentry *dentry)
2669+{
2670+ struct dentry *parent, *hasone;
2671+ int bindex = dbstart(dentry);
2672+
2673+ if (unionfs_lower_mnt_idx(dentry, bindex))
2674+ return;
2675+ hasone = dentry->d_parent;
2676+ /* this loop should stop at root dentry */
2677+ while (!unionfs_lower_mnt_idx(hasone, bindex))
2678+ hasone = hasone->d_parent;
2679+ parent = dentry;
2680+ while (!unionfs_lower_mnt_idx(parent, bindex)) {
2681+ unionfs_set_lower_mnt_idx(parent, bindex,
2682+ unionfs_mntget(hasone, bindex));
2683+ parent = parent->d_parent;
2684+ }
2685+}
2686+
2687+/*
2688+ * Post-copyup helper to release all non-directory source objects of a
2689+ * copied-up file. Regular files should have only one lower object.
2690+ */
2691+void unionfs_postcopyup_release(struct dentry *dentry)
2692+{
2693+ int bstart, bend;
2694+
2695+ BUG_ON(S_ISDIR(dentry->d_inode->i_mode));
2696+ bstart = dbstart(dentry);
2697+ bend = dbend(dentry);
2698+
2699+ path_put_lowers(dentry, bstart + 1, bend, false);
2700+ iput_lowers(dentry->d_inode, bstart + 1, bend, false);
2701+
2702+ dbend(dentry) = bstart;
2703+ ibend(dentry->d_inode) = ibstart(dentry->d_inode) = bstart;
2704+}
2705diff --git a/fs/unionfs/debug.c b/fs/unionfs/debug.c
2706new file mode 100644
2707index 0000000..db62d22
2708--- /dev/null
2709+++ b/fs/unionfs/debug.c
2710@@ -0,0 +1,533 @@
2711+/*
2712+ * Copyright (c) 2003-2008 Erez Zadok
2713+ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
2714+ * Copyright (c) 2003-2008 Stony Brook University
2715+ * Copyright (c) 2003-2008 The Research Foundation of SUNY
2716+ *
2717+ * This program is free software; you can redistribute it and/or modify
2718+ * it under the terms of the GNU General Public License version 2 as
2719+ * published by the Free Software Foundation.
2720+ */
2721+
2722+#include "union.h"
2723+
2724+/*
2725+ * Helper debugging functions for maintainers (and for users to report back
2726+ * useful information back to maintainers)
2727+ */
2728+
2729+/* it's always useful to know what part of the code called us */
2730+#define PRINT_CALLER(fname, fxn, line) \
2731+ do { \
2732+ if (!printed_caller) { \
2733+ pr_debug("PC:%s:%s:%d\n", (fname), (fxn), (line)); \
2734+ printed_caller = 1; \
2735+ } \
2736+ } while (0)
2737+
2738+/*
2739+ * __unionfs_check_{inode,dentry,file} perform exhaustive sanity checking on
2740+ * the fan-out of various Unionfs objects. We check that no lower objects
2741+ * exist outside the start/end branch range; that all objects within are
2742+ * non-NULL (with some allowed exceptions); that for every lower file
2743+ * there's a lower dentry+inode; that the start/end ranges match for all
2744+ * corresponding lower objects; that open files/symlinks have only one lower
2745+ * objects, but directories can have several; and more.
2746+ */
2747+void __unionfs_check_inode(const struct inode *inode,
2748+ const char *fname, const char *fxn, int line)
2749+{
2750+ int bindex;
2751+ int istart, iend;
2752+ struct inode *lower_inode;
2753+ struct super_block *sb;
2754+ int printed_caller = 0;
2755+ void *poison_ptr;
2756+
2757+ /* for inodes now */
2758+ BUG_ON(!inode);
2759+ sb = inode->i_sb;
2760+ istart = ibstart(inode);
2761+ iend = ibend(inode);
2762+ /* don't check inode if no lower branches */
2763+ if (istart < 0 && iend < 0)
2764+ return;
2765+ if (unlikely(istart > iend)) {
2766+ PRINT_CALLER(fname, fxn, line);
2767+ pr_debug(" Ci0: inode=%p istart/end=%d:%d\n",
2768+ inode, istart, iend);
2769+ }
2770+ if (unlikely((istart == -1 && iend != -1) ||
2771+ (istart != -1 && iend == -1))) {
2772+ PRINT_CALLER(fname, fxn, line);
2773+ pr_debug(" Ci1: inode=%p istart/end=%d:%d\n",
2774+ inode, istart, iend);
2775+ }
2776+ if (!S_ISDIR(inode->i_mode)) {
2777+ if (unlikely(iend != istart)) {
2778+ PRINT_CALLER(fname, fxn, line);
2779+ pr_debug(" Ci2: inode=%p istart=%d iend=%d\n",
2780+ inode, istart, iend);
2781+ }
2782+ }
2783+
2784+ for (bindex = sbstart(sb); bindex < sbmax(sb); bindex++) {
2785+ if (unlikely(!UNIONFS_I(inode))) {
2786+ PRINT_CALLER(fname, fxn, line);
2787+ pr_debug(" Ci3: no inode_info %p\n", inode);
2788+ return;
2789+ }
2790+ if (unlikely(!UNIONFS_I(inode)->lower_inodes)) {
2791+ PRINT_CALLER(fname, fxn, line);
2792+ pr_debug(" Ci4: no lower_inodes %p\n", inode);
2793+ return;
2794+ }
2795+ lower_inode = unionfs_lower_inode_idx(inode, bindex);
2796+ if (lower_inode) {
2797+ memset(&poison_ptr, POISON_INUSE, sizeof(void *));
2798+ if (unlikely(bindex < istart || bindex > iend)) {
2799+ PRINT_CALLER(fname, fxn, line);
2800+ pr_debug(" Ci5: inode/linode=%p:%p bindex=%d "
2801+ "istart/end=%d:%d\n", inode,
2802+ lower_inode, bindex, istart, iend);
2803+ } else if (unlikely(lower_inode == poison_ptr)) {
2804+ /* freed inode! */
2805+ PRINT_CALLER(fname, fxn, line);
2806+ pr_debug(" Ci6: inode/linode=%p:%p bindex=%d "
2807+ "istart/end=%d:%d\n", inode,
2808+ lower_inode, bindex, istart, iend);
2809+ }
2810+ continue;
2811+ }
2812+ /* if we get here, then lower_inode == NULL */
2813+ if (bindex < istart || bindex > iend)
2814+ continue;
2815+ /*
2816+ * directories can have NULL lower inodes in b/t start/end,
2817+ * but NOT if at the start/end range.
2818+ */
2819+ if (unlikely(S_ISDIR(inode->i_mode) &&
2820+ bindex > istart && bindex < iend))
2821+ continue;
2822+ PRINT_CALLER(fname, fxn, line);
2823+ pr_debug(" Ci7: inode/linode=%p:%p "
2824+ "bindex=%d istart/end=%d:%d\n",
2825+ inode, lower_inode, bindex, istart, iend);
2826+ }
2827+}
2828+
2829+void __unionfs_check_dentry(const struct dentry *dentry,
2830+ const char *fname, const char *fxn, int line)
2831+{
2832+ int bindex;
2833+ int dstart, dend, istart, iend;
2834+ struct dentry *lower_dentry;
2835+ struct inode *inode, *lower_inode;
2836+ struct super_block *sb;
2837+ struct vfsmount *lower_mnt;
2838+ int printed_caller = 0;
2839+ void *poison_ptr;
2840+
2841+ BUG_ON(!dentry);
2842+ sb = dentry->d_sb;
2843+ inode = dentry->d_inode;
2844+ dstart = dbstart(dentry);
2845+ dend = dbend(dentry);
2846+ /* don't check dentry/mnt if no lower branches */
2847+ if (dstart < 0 && dend < 0)
2848+ goto check_inode;
2849+ BUG_ON(dstart > dend);
2850+
2851+ if (unlikely((dstart == -1 && dend != -1) ||
2852+ (dstart != -1 && dend == -1))) {
2853+ PRINT_CALLER(fname, fxn, line);
2854+ pr_debug(" CD0: dentry=%p dstart/end=%d:%d\n",
2855+ dentry, dstart, dend);
2856+ }
2857+ /*
2858+ * check for NULL dentries inside the start/end range, or
2859+ * non-NULL dentries outside the start/end range.
2860+ */
2861+ for (bindex = sbstart(sb); bindex < sbmax(sb); bindex++) {
2862+ lower_dentry = unionfs_lower_dentry_idx(dentry, bindex);
2863+ if (lower_dentry) {
2864+ if (unlikely(bindex < dstart || bindex > dend)) {
2865+ PRINT_CALLER(fname, fxn, line);
2866+ pr_debug(" CD1: dentry/lower=%p:%p(%p) "
2867+ "bindex=%d dstart/end=%d:%d\n",
2868+ dentry, lower_dentry,
2869+ (lower_dentry ? lower_dentry->d_inode :
2870+ (void *) -1L),
2871+ bindex, dstart, dend);
2872+ }
2873+ } else { /* lower_dentry == NULL */
2874+ if (bindex < dstart || bindex > dend)
2875+ continue;
2876+ /*
2877+ * Directories can have NULL lower inodes in b/t
2878+ * start/end, but NOT if at the start/end range.
2879+ * Ignore this rule, however, if this is a NULL
2880+ * dentry or a deleted dentry.
2881+ */
2882+ if (unlikely(!d_deleted((struct dentry *) dentry) &&
2883+ inode &&
2884+ !(inode && S_ISDIR(inode->i_mode) &&
2885+ bindex > dstart && bindex < dend))) {
2886+ PRINT_CALLER(fname, fxn, line);
2887+ pr_debug(" CD2: dentry/lower=%p:%p(%p) "
2888+ "bindex=%d dstart/end=%d:%d\n",
2889+ dentry, lower_dentry,
2890+ (lower_dentry ?
2891+ lower_dentry->d_inode :
2892+ (void *) -1L),
2893+ bindex, dstart, dend);
2894+ }
2895+ }
2896+ }
2897+
2898+ /* check for vfsmounts same as for dentries */
2899+ for (bindex = sbstart(sb); bindex < sbmax(sb); bindex++) {
2900+ lower_mnt = unionfs_lower_mnt_idx(dentry, bindex);
2901+ if (lower_mnt) {
2902+ if (unlikely(bindex < dstart || bindex > dend)) {
2903+ PRINT_CALLER(fname, fxn, line);
2904+ pr_debug(" CM0: dentry/lmnt=%p:%p bindex=%d "
2905+ "dstart/end=%d:%d\n", dentry,
2906+ lower_mnt, bindex, dstart, dend);
2907+ }
2908+ } else { /* lower_mnt == NULL */
2909+ if (bindex < dstart || bindex > dend)
2910+ continue;
2911+ /*
2912+ * Directories can have NULL lower inodes in b/t
2913+ * start/end, but NOT if at the start/end range.
2914+ * Ignore this rule, however, if this is a NULL
2915+ * dentry.
2916+ */
2917+ if (unlikely(inode &&
2918+ !(inode && S_ISDIR(inode->i_mode) &&
2919+ bindex > dstart && bindex < dend))) {
2920+ PRINT_CALLER(fname, fxn, line);
2921+ pr_debug(" CM1: dentry/lmnt=%p:%p "
2922+ "bindex=%d dstart/end=%d:%d\n",
2923+ dentry, lower_mnt, bindex,
2924+ dstart, dend);
2925+ }
2926+ }
2927+ }
2928+
2929+check_inode:
2930+ /* for inodes now */
2931+ if (!inode)
2932+ return;
2933+ istart = ibstart(inode);
2934+ iend = ibend(inode);
2935+ /* don't check inode if no lower branches */
2936+ if (istart < 0 && iend < 0)
2937+ return;
2938+ BUG_ON(istart > iend);
2939+ if (unlikely((istart == -1 && iend != -1) ||
2940+ (istart != -1 && iend == -1))) {
2941+ PRINT_CALLER(fname, fxn, line);
2942+ pr_debug(" CI0: dentry/inode=%p:%p istart/end=%d:%d\n",
2943+ dentry, inode, istart, iend);
2944+ }
2945+ if (unlikely(istart != dstart)) {
2946+ PRINT_CALLER(fname, fxn, line);
2947+ pr_debug(" CI1: dentry/inode=%p:%p istart=%d dstart=%d\n",
2948+ dentry, inode, istart, dstart);
2949+ }
2950+ if (unlikely(iend != dend)) {
2951+ PRINT_CALLER(fname, fxn, line);
2952+ pr_debug(" CI2: dentry/inode=%p:%p iend=%d dend=%d\n",
2953+ dentry, inode, iend, dend);
2954+ }
2955+
2956+ if (!S_ISDIR(inode->i_mode)) {
2957+ if (unlikely(dend != dstart)) {
2958+ PRINT_CALLER(fname, fxn, line);
2959+ pr_debug(" CI3: dentry/inode=%p:%p dstart=%d dend=%d\n",
2960+ dentry, inode, dstart, dend);
2961+ }
2962+ if (unlikely(iend != istart)) {
2963+ PRINT_CALLER(fname, fxn, line);
2964+ pr_debug(" CI4: dentry/inode=%p:%p istart=%d iend=%d\n",
2965+ dentry, inode, istart, iend);
2966+ }
2967+ }
2968+
2969+ for (bindex = sbstart(sb); bindex < sbmax(sb); bindex++) {
2970+ lower_inode = unionfs_lower_inode_idx(inode, bindex);
2971+ if (lower_inode) {
2972+ memset(&poison_ptr, POISON_INUSE, sizeof(void *));
2973+ if (unlikely(bindex < istart || bindex > iend)) {
2974+ PRINT_CALLER(fname, fxn, line);
2975+ pr_debug(" CI5: dentry/linode=%p:%p bindex=%d "
2976+ "istart/end=%d:%d\n", dentry,
2977+ lower_inode, bindex, istart, iend);
2978+ } else if (unlikely(lower_inode == poison_ptr)) {
2979+ /* freed inode! */
2980+ PRINT_CALLER(fname, fxn, line);
2981+ pr_debug(" CI6: dentry/linode=%p:%p bindex=%d "
2982+ "istart/end=%d:%d\n", dentry,
2983+ lower_inode, bindex, istart, iend);
2984+ }
2985+ continue;
2986+ }
2987+ /* if we get here, then lower_inode == NULL */
2988+ if (bindex < istart || bindex > iend)
2989+ continue;
2990+ /*
2991+ * directories can have NULL lower inodes in b/t start/end,
2992+ * but NOT if at the start/end range.
2993+ */
2994+ if (unlikely(S_ISDIR(inode->i_mode) &&
2995+ bindex > istart && bindex < iend))
2996+ continue;
2997+ PRINT_CALLER(fname, fxn, line);
2998+ pr_debug(" CI7: dentry/linode=%p:%p "
2999+ "bindex=%d istart/end=%d:%d\n",
3000+ dentry, lower_inode, bindex, istart, iend);
3001+ }
3002+
3003+ /*
3004+ * If it's a directory, then intermediate objects b/t start/end can
3005+ * be NULL. But, check that all three are NULL: lower dentry, mnt,
3006+ * and inode.
3007+ */
3008+ if (dstart >= 0 && dend >= 0 && S_ISDIR(inode->i_mode))
3009+ for (bindex = dstart+1; bindex < dend; bindex++) {
3010+ lower_inode = unionfs_lower_inode_idx(inode, bindex);
3011+ lower_dentry = unionfs_lower_dentry_idx(dentry,
3012+ bindex);
3013+ lower_mnt = unionfs_lower_mnt_idx(dentry, bindex);
3014+ if (unlikely(!((lower_inode && lower_dentry &&
3015+ lower_mnt) ||
3016+ (!lower_inode &&
3017+ !lower_dentry && !lower_mnt)))) {
3018+ PRINT_CALLER(fname, fxn, line);
3019+ pr_debug(" Cx: lmnt/ldentry/linode=%p:%p:%p "
3020+ "bindex=%d dstart/end=%d:%d\n",
3021+ lower_mnt, lower_dentry, lower_inode,
3022+ bindex, dstart, dend);
3023+ }
3024+ }
3025+ /* check if lower inode is newer than upper one (it shouldn't) */
3026+ if (unlikely(is_newer_lower(dentry) && !is_negative_lower(dentry))) {
3027+ PRINT_CALLER(fname, fxn, line);
3028+ for (bindex = ibstart(inode); bindex <= ibend(inode);
3029+ bindex++) {
3030+ lower_inode = unionfs_lower_inode_idx(inode, bindex);
3031+ if (unlikely(!lower_inode))
3032+ continue;
3033+ pr_debug(" CI8: bindex=%d mtime/lmtime=%lu.%lu/%lu.%lu "
3034+ "ctime/lctime=%lu.%lu/%lu.%lu\n",
3035+ bindex,
3036+ inode->i_mtime.tv_sec,
3037+ inode->i_mtime.tv_nsec,
3038+ lower_inode->i_mtime.tv_sec,
3039+ lower_inode->i_mtime.tv_nsec,
3040+ inode->i_ctime.tv_sec,
3041+ inode->i_ctime.tv_nsec,
3042+ lower_inode->i_ctime.tv_sec,
3043+ lower_inode->i_ctime.tv_nsec);
3044+ }
3045+ }
3046+}
3047+
3048+void __unionfs_check_file(const struct file *file,
3049+ const char *fname, const char *fxn, int line)
3050+{
3051+ int bindex;
3052+ int dstart, dend, fstart, fend;
3053+ struct dentry *dentry;
3054+ struct file *lower_file;
3055+ struct inode *inode;
3056+ struct super_block *sb;
3057+ int printed_caller = 0;
3058+
3059+ BUG_ON(!file);
3060+ dentry = file->f_path.dentry;
3061+ sb = dentry->d_sb;
3062+ dstart = dbstart(dentry);
3063+ dend = dbend(dentry);
3064+ BUG_ON(dstart > dend);
3065+ fstart = fbstart(file);
3066+ fend = fbend(file);
3067+ BUG_ON(fstart > fend);
3068+
3069+ if (unlikely((fstart == -1 && fend != -1) ||
3070+ (fstart != -1 && fend == -1))) {
3071+ PRINT_CALLER(fname, fxn, line);
3072+ pr_debug(" CF0: file/dentry=%p:%p fstart/end=%d:%d\n",
3073+ file, dentry, fstart, fend);
3074+ }
3075+ if (unlikely(fstart != dstart)) {
3076+ PRINT_CALLER(fname, fxn, line);
3077+ pr_debug(" CF1: file/dentry=%p:%p fstart=%d dstart=%d\n",
3078+ file, dentry, fstart, dstart);
3079+ }
3080+ if (unlikely(fend != dend)) {
3081+ PRINT_CALLER(fname, fxn, line);
3082+ pr_debug(" CF2: file/dentry=%p:%p fend=%d dend=%d\n",
3083+ file, dentry, fend, dend);
3084+ }
3085+ inode = dentry->d_inode;
3086+ if (!S_ISDIR(inode->i_mode)) {
3087+ if (unlikely(fend != fstart)) {
3088+ PRINT_CALLER(fname, fxn, line);
3089+ pr_debug(" CF3: file/inode=%p:%p fstart=%d fend=%d\n",
3090+ file, inode, fstart, fend);
3091+ }
3092+ if (unlikely(dend != dstart)) {
3093+ PRINT_CALLER(fname, fxn, line);
3094+ pr_debug(" CF4: file/dentry=%p:%p dstart=%d dend=%d\n",
3095+ file, dentry, dstart, dend);
3096+ }
3097+ }
3098+
3099+ /*
3100+ * check for NULL dentries inside the start/end range, or
3101+ * non-NULL dentries outside the start/end range.
3102+ */
3103+ for (bindex = sbstart(sb); bindex < sbmax(sb); bindex++) {
3104+ lower_file = unionfs_lower_file_idx(file, bindex);
3105+ if (lower_file) {
3106+ if (unlikely(bindex < fstart || bindex > fend)) {
3107+ PRINT_CALLER(fname, fxn, line);
3108+ pr_debug(" CF5: file/lower=%p:%p bindex=%d "
3109+ "fstart/end=%d:%d\n", file,
3110+ lower_file, bindex, fstart, fend);
3111+ }
3112+ } else { /* lower_file == NULL */
3113+ if (bindex >= fstart && bindex <= fend) {
3114+ /*
3115+ * directories can have NULL lower inodes in
3116+ * b/t start/end, but NOT if at the
3117+ * start/end range.
3118+ */
3119+ if (unlikely(!(S_ISDIR(inode->i_mode) &&
3120+ bindex > fstart &&
3121+ bindex < fend))) {
3122+ PRINT_CALLER(fname, fxn, line);
3123+ pr_debug(" CF6: file/lower=%p:%p "
3124+ "bindex=%d fstart/end=%d:%d\n",
3125+ file, lower_file, bindex,
3126+ fstart, fend);
3127+ }
3128+ }
3129+ }
3130+ }
3131+
3132+ __unionfs_check_dentry(dentry, fname, fxn, line);
3133+}
3134+
3135+void __unionfs_check_nd(const struct nameidata *nd,
3136+ const char *fname, const char *fxn, int line)
3137+{
3138+ struct file *file;
3139+ int printed_caller = 0;
3140+
3141+ if (unlikely(!nd))
3142+ return;
3143+ if (nd->flags & LOOKUP_OPEN) {
3144+ file = nd->intent.open.file;
3145+ if (unlikely(file->f_path.dentry &&
3146+ strcmp(file->f_path.dentry->d_sb->s_type->name,
3147+ UNIONFS_NAME))) {
3148+ PRINT_CALLER(fname, fxn, line);
3149+ pr_debug(" CND1: lower_file of type %s\n",
3150+ file->f_path.dentry->d_sb->s_type->name);
3151+ BUG();
3152+ }
3153+ }
3154+}
3155+
3156+/* useful to track vfsmount leaks that could cause EBUSY on unmount */
3157+void __show_branch_counts(const struct super_block *sb,
3158+ const char *file, const char *fxn, int line)
3159+{
3160+ int i;
3161+ struct vfsmount *mnt;
3162+
3163+ pr_debug("BC:");
3164+ for (i = 0; i < sbmax(sb); i++) {
3165+ if (likely(sb->s_root))
3166+ mnt = UNIONFS_D(sb->s_root)->lower_paths[i].mnt;
3167+ else
3168+ mnt = NULL;
3169+ printk(KERN_CONT "%d:",
3170+ (mnt ? atomic_read(&mnt->mnt_count) : -99));
3171+ }
3172+ printk(KERN_CONT "%s:%s:%d\n", file, fxn, line);
3173+}
3174+
3175+void __show_inode_times(const struct inode *inode,
3176+ const char *file, const char *fxn, int line)
3177+{
3178+ struct inode *lower_inode;
3179+ int bindex;
3180+
3181+ for (bindex = ibstart(inode); bindex <= ibend(inode); bindex++) {
3182+ lower_inode = unionfs_lower_inode_idx(inode, bindex);
3183+ if (unlikely(!lower_inode))
3184+ continue;
3185+ pr_debug("IT(%lu:%d): %s:%s:%d "
3186+ "um=%lu/%lu lm=%lu/%lu uc=%lu/%lu lc=%lu/%lu\n",
3187+ inode->i_ino, bindex,
3188+ file, fxn, line,
3189+ inode->i_mtime.tv_sec, inode->i_mtime.tv_nsec,
3190+ lower_inode->i_mtime.tv_sec,
3191+ lower_inode->i_mtime.tv_nsec,
3192+ inode->i_ctime.tv_sec, inode->i_ctime.tv_nsec,
3193+ lower_inode->i_ctime.tv_sec,
3194+ lower_inode->i_ctime.tv_nsec);
3195+ }
3196+}
3197+
3198+void __show_dinode_times(const struct dentry *dentry,
3199+ const char *file, const char *fxn, int line)
3200+{
3201+ struct inode *inode = dentry->d_inode;
3202+ struct inode *lower_inode;
3203+ int bindex;
3204+
3205+ for (bindex = ibstart(inode); bindex <= ibend(inode); bindex++) {
3206+ lower_inode = unionfs_lower_inode_idx(inode, bindex);
3207+ if (!lower_inode)
3208+ continue;
3209+ pr_debug("DT(%s:%lu:%d): %s:%s:%d "
3210+ "um=%lu/%lu lm=%lu/%lu uc=%lu/%lu lc=%lu/%lu\n",
3211+ dentry->d_name.name, inode->i_ino, bindex,
3212+ file, fxn, line,
3213+ inode->i_mtime.tv_sec, inode->i_mtime.tv_nsec,
3214+ lower_inode->i_mtime.tv_sec,
3215+ lower_inode->i_mtime.tv_nsec,
3216+ inode->i_ctime.tv_sec, inode->i_ctime.tv_nsec,
3217+ lower_inode->i_ctime.tv_sec,
3218+ lower_inode->i_ctime.tv_nsec);
3219+ }
3220+}
3221+
3222+void __show_inode_counts(const struct inode *inode,
3223+ const char *file, const char *fxn, int line)
3224+{
3225+ struct inode *lower_inode;
3226+ int bindex;
3227+
3228+ if (unlikely(!inode)) {
3229+ pr_debug("SiC: Null inode\n");
3230+ return;
3231+ }
3232+ for (bindex = sbstart(inode->i_sb); bindex <= sbend(inode->i_sb);
3233+ bindex++) {
3234+ lower_inode = unionfs_lower_inode_idx(inode, bindex);
3235+ if (unlikely(!lower_inode))
3236+ continue;
3237+ pr_debug("SIC(%lu:%d:%d): lc=%d %s:%s:%d\n",
3238+ inode->i_ino, bindex,
3239+ atomic_read(&(inode)->i_count),
3240+ atomic_read(&(lower_inode)->i_count),
3241+ file, fxn, line);
3242+ }
3243+}
3244diff --git a/fs/unionfs/dentry.c b/fs/unionfs/dentry.c
3245new file mode 100644
3246index 0000000..7f0c7f7
3247--- /dev/null
3248+++ b/fs/unionfs/dentry.c
3249@@ -0,0 +1,570 @@
3250+/*
3251+ * Copyright (c) 2003-2008 Erez Zadok
3252+ * Copyright (c) 2003-2006 Charles P. Wright
3253+ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
3254+ * Copyright (c) 2005-2006 Junjiro Okajima
3255+ * Copyright (c) 2005 Arun M. Krishnakumar
3256+ * Copyright (c) 2004-2006 David P. Quigley
3257+ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
3258+ * Copyright (c) 2003 Puja Gupta
3259+ * Copyright (c) 2003 Harikesavan Krishnan
3260+ * Copyright (c) 2003-2008 Stony Brook University
3261+ * Copyright (c) 2003-2008 The Research Foundation of SUNY
3262+ *
3263+ * This program is free software; you can redistribute it and/or modify
3264+ * it under the terms of the GNU General Public License version 2 as
3265+ * published by the Free Software Foundation.
3266+ */
3267+
3268+#include "union.h"
3269+
3270+bool is_negative_lower(const struct dentry *dentry)
3271+{
3272+ int bindex;
3273+ struct dentry *lower_dentry;
3274+
3275+ BUG_ON(!dentry);
3276+ /* cache coherency: check if file was deleted on lower branch */
3277+ if (dbstart(dentry) < 0)
3278+ return true;
3279+ for (bindex = dbstart(dentry); bindex <= dbend(dentry); bindex++) {
3280+ lower_dentry = unionfs_lower_dentry_idx(dentry, bindex);
3281+ /* unhashed (i.e., unlinked) lower dentries don't count */
3282+ if (lower_dentry && lower_dentry->d_inode &&
3283+ !d_deleted(lower_dentry) &&
3284+ !(lower_dentry->d_flags & DCACHE_NFSFS_RENAMED))
3285+ return false;
3286+ }
3287+ return true;
3288+}
3289+
3290+static inline void __dput_lowers(struct dentry *dentry, int start, int end)
3291+{
3292+ struct dentry *lower_dentry;
3293+ int bindex;
3294+
3295+ if (start < 0)
3296+ return;
3297+ for (bindex = start; bindex <= end; bindex++) {
3298+ lower_dentry = unionfs_lower_dentry_idx(dentry, bindex);
3299+ if (!lower_dentry)
3300+ continue;
3301+ unionfs_set_lower_dentry_idx(dentry, bindex, NULL);
3302+ dput(lower_dentry);
3303+ }
3304+}
3305+
3306+/*
3307+ * Revalidate a single dentry.
3308+ * Assume that dentry's info node is locked.
3309+ * Assume that parent(s) are all valid already, but
3310+ * the child may not yet be valid.
3311+ * Returns true if valid, false otherwise.
3312+ */
3313+static bool __unionfs_d_revalidate_one(struct dentry *dentry,
3314+ struct nameidata *nd)
3315+{
3316+ bool valid = true; /* default is valid */
3317+ struct dentry *lower_dentry;
3318+ int bindex, bstart, bend;
3319+ int sbgen, dgen;
3320+ int positive = 0;
3321+ int interpose_flag;
3322+ struct nameidata lowernd; /* TODO: be gentler to the stack */
3323+
3324+ if (nd)
3325+ memcpy(&lowernd, nd, sizeof(struct nameidata));
3326+ else
3327+ memset(&lowernd, 0, sizeof(struct nameidata));
3328+
3329+ verify_locked(dentry);
3330+ verify_locked(dentry->d_parent);
3331+
3332+ sbgen = atomic_read(&UNIONFS_SB(dentry->d_sb)->generation);
3333+ /* if the dentry is unhashed, do NOT revalidate */
3334+ if (d_deleted(dentry))
3335+ goto out;
3336+
3337+ BUG_ON(dbstart(dentry) == -1);
3338+ if (dentry->d_inode)
3339+ positive = 1;
3340+ dgen = atomic_read(&UNIONFS_D(dentry)->generation);
3341+ /*
3342+ * If we are working on an unconnected dentry, then there is no
3343+ * revalidation to be done, because this file does not exist within
3344+ * the namespace, and Unionfs operates on the namespace, not data.
3345+ */
3346+ if (unlikely(sbgen != dgen)) {
3347+ struct dentry *result;
3348+ int pdgen;
3349+
3350+ /* The root entry should always be valid */
3351+ BUG_ON(IS_ROOT(dentry));
3352+
3353+ /* We can't work correctly if our parent isn't valid. */
3354+ pdgen = atomic_read(&UNIONFS_D(dentry->d_parent)->generation);
3355+ BUG_ON(pdgen != sbgen); /* should never happen here */
3356+
3357+ /* Free the pointers for our inodes and this dentry. */
3358+ bstart = dbstart(dentry);
3359+ bend = dbend(dentry);
3360+
3361+ /*
3362+ * mntput unhashed lower dentries, because those files got
3363+ * deleted or rmdir'ed.
3364+ */
3365+ for (bindex = bstart; bindex <= bend; bindex++) {
3366+ lower_dentry = unionfs_lower_dentry_idx(dentry, bindex);
3367+ if (!lower_dentry)
3368+ continue;
3369+ if (!d_deleted(lower_dentry) &&
3370+ !(lower_dentry->d_flags & DCACHE_NFSFS_RENAMED))
3371+ continue;
3372+ unionfs_mntput(dentry, bindex);
3373+ }
3374+
3375+ __dput_lowers(dentry, bstart, bend);
3376+ dbstart(dentry) = dbend(dentry) = -1;
3377+
3378+ interpose_flag = INTERPOSE_REVAL_NEG;
3379+ if (positive) {
3380+ interpose_flag = INTERPOSE_REVAL;
3381+ iput_lowers_all(dentry->d_inode, true);
3382+ }
3383+
3384+ if (realloc_dentry_private_data(dentry) != 0) {
3385+ valid = false;
3386+ goto out;
3387+ }
3388+
3389+ result = unionfs_lookup_full(dentry, &lowernd, interpose_flag);
3390+ if (result) {
3391+ if (IS_ERR(result)) {
3392+ valid = false;
3393+ goto out;
3394+ }
3395+ /*
3396+ * current unionfs_lookup_backend() doesn't return
3397+ * a valid dentry
3398+ */
3399+ dput(dentry);
3400+ dentry = result;
3401+ }
3402+
3403+ if (unlikely(positive && is_negative_lower(dentry))) {
3404+ make_bad_inode(dentry->d_inode);
3405+ d_drop(dentry);
3406+ valid = false;
3407+ goto out;
3408+ }
3409+ goto out;
3410+ }
3411+
3412+ /* The revalidation must occur across all branches */
3413+ bstart = dbstart(dentry);
3414+ bend = dbend(dentry);
3415+ BUG_ON(bstart == -1);
3416+ for (bindex = bstart; bindex <= bend; bindex++) {
3417+ lower_dentry = unionfs_lower_dentry_idx(dentry, bindex);
3418+ if (!lower_dentry || !lower_dentry->d_op
3419+ || !lower_dentry->d_op->d_revalidate)
3420+ continue;
3421+ /*
3422+ * Don't pass nameidata to lower file system, because we
3423+ * don't want an arbitrary lower file being opened or
3424+ * returned to us: it may be useless to us because of the
3425+ * fanout nature of unionfs (cf. file/directory open-file
3426+ * invariants). We will open lower files as and when needed
3427+ * later on.
3428+ */
3429+ if (!lower_dentry->d_op->d_revalidate(lower_dentry, NULL))
3430+ valid = false;
3431+ }
3432+
3433+ if (!dentry->d_inode ||
3434+ ibstart(dentry->d_inode) < 0 ||
3435+ ibend(dentry->d_inode) < 0) {
3436+ valid = false;
3437+ goto out;
3438+ }
3439+
3440+ if (valid) {
3441+ /*
3442+ * If we get here, and we copy the meta-data from the lower
3443+ * inode to our inode, then it is vital that we have already
3444+ * purged all unionfs-level file data. We do that in the
3445+ * caller (__unionfs_d_revalidate_chain) by calling
3446+ * purge_inode_data.
3447+ */
3448+ unionfs_copy_attr_all(dentry->d_inode,
3449+ unionfs_lower_inode(dentry->d_inode));
3450+ fsstack_copy_inode_size(dentry->d_inode,
3451+ unionfs_lower_inode(dentry->d_inode));
3452+ }
3453+
3454+out:
3455+ if (valid)
3456+ atomic_set(&UNIONFS_D(dentry)->generation, sbgen);
3457+
3458+ return valid;
3459+}
3460+
3461+/*
3462+ * Determine if the lower inode objects have changed from below the unionfs
3463+ * inode. Return true if changed, false otherwise.
3464+ *
3465+ * We check if the mtime or ctime have changed. However, the inode times
3466+ * can be changed by anyone without much protection, including
3467+ * asynchronously. This can sometimes cause unionfs to find that the lower
3468+ * file system doesn't change its inode times quick enough, resulting in a
3469+ * false positive indication (which is harmless, it just makes unionfs do
3470+ * extra work in re-validating the objects). To minimize the chances of
3471+ * these situations, we still consider such small time changes valid, but we
3472+ * don't print debugging messages unless the time changes are greater than
3473+ * UNIONFS_MIN_CC_TIME (which defaults to 3 seconds, as with NFS's acregmin)
3474+ * because significant changes are more likely due to users manually
3475+ * touching lower files.
3476+ */
3477+bool is_newer_lower(const struct dentry *dentry)
3478+{
3479+ int bindex;
3480+ struct inode *inode;
3481+ struct inode *lower_inode;
3482+
3483+ /* ignore if we're called on semi-initialized dentries/inodes */
3484+ if (!dentry || !UNIONFS_D(dentry))
3485+ return false;
3486+ inode = dentry->d_inode;
3487+ if (!inode || !UNIONFS_I(inode)->lower_inodes ||
3488+ ibstart(inode) < 0 || ibend(inode) < 0)
3489+ return false;
3490+
3491+ for (bindex = ibstart(inode); bindex <= ibend(inode); bindex++) {
3492+ lower_inode = unionfs_lower_inode_idx(inode, bindex);
3493+ if (!lower_inode)
3494+ continue;
3495+
3496+ /* check if mtime/ctime have changed */
3497+ if (unlikely(timespec_compare(&inode->i_mtime,
3498+ &lower_inode->i_mtime) < 0)) {
3499+ if ((lower_inode->i_mtime.tv_sec -
3500+ inode->i_mtime.tv_sec) > UNIONFS_MIN_CC_TIME) {
3501+ pr_info("unionfs: new lower inode mtime "
3502+ "(bindex=%d, name=%s)\n", bindex,
3503+ dentry->d_name.name);
3504+ show_dinode_times(dentry);
3505+ }
3506+ return true;
3507+ }
3508+ if (unlikely(timespec_compare(&inode->i_ctime,
3509+ &lower_inode->i_ctime) < 0)) {
3510+ if ((lower_inode->i_ctime.tv_sec -
3511+ inode->i_ctime.tv_sec) > UNIONFS_MIN_CC_TIME) {
3512+ pr_info("unionfs: new lower inode ctime "
3513+ "(bindex=%d, name=%s)\n", bindex,
3514+ dentry->d_name.name);
3515+ show_dinode_times(dentry);
3516+ }
3517+ return true;
3518+ }
3519+ }
3520+
3521+ /*
3522+ * Last check: if this is a positive dentry, but somehow all lower
3523+ * dentries are negative or unhashed, then this dentry needs to be
3524+ * revalidated, because someone probably deleted the objects from
3525+ * the lower branches directly.
3526+ */
3527+ if (is_negative_lower(dentry))
3528+ return true;
3529+
3530+ return false; /* default: lower is not newer */
3531+}
3532+
3533+/*
3534+ * Purge and invalidate as many data pages of a unionfs inode. This is
3535+ * called when the lower inode has changed, and we want to force processes
3536+ * to re-get the new data.
3537+ */
3538+static inline void purge_inode_data(struct inode *inode)
3539+{
3540+ /* remove all non-private mappings */
3541+ unmap_mapping_range(inode->i_mapping, 0, 0, 0);
3542+ /* invalidate as many pages as possible */
3543+ invalidate_mapping_pages(inode->i_mapping, 0, -1);
3544+ /*
3545+ * Don't try to truncate_inode_pages here, because this could lead
3546+ * to a deadlock between some of address_space ops and dentry
3547+ * revalidation: the address space op is invoked with a lock on our
3548+ * own page, and truncate_inode_pages will block on locked pages.
3549+ */
3550+}
3551+
3552+/*
3553+ * Revalidate a single file/symlink/special dentry. Assume that info nodes
3554+ * of the dentry and its parent are locked. Assume that parent(s) are all
3555+ * valid already, but the child may not yet be valid. Returns true if
3556+ * valid, false otherwise.
3557+ */
3558+bool __unionfs_d_revalidate_one_locked(struct dentry *dentry,
3559+ struct nameidata *nd,
3560+ bool willwrite)
3561+{
3562+ bool valid = false; /* default is invalid */
3563+ int sbgen, dgen, bindex;
3564+
3565+ verify_locked(dentry);
3566+ verify_locked(dentry->d_parent);
3567+
3568+ sbgen = atomic_read(&UNIONFS_SB(dentry->d_sb)->generation);
3569+ dgen = atomic_read(&UNIONFS_D(dentry)->generation);
3570+
3571+ if (unlikely(is_newer_lower(dentry))) {
3572+ /* root dentry special case as aforementioned */
3573+ if (IS_ROOT(dentry)) {
3574+ unionfs_copy_attr_times(dentry->d_inode);
3575+ } else {
3576+ /*
3577+ * reset generation number to zero, guaranteed to be
3578+ * "old"
3579+ */
3580+ dgen = 0;
3581+ atomic_set(&UNIONFS_D(dentry)->generation, dgen);
3582+ }
3583+ if (!willwrite)
3584+ purge_inode_data(dentry->d_inode);
3585+ }
3586+ valid = __unionfs_d_revalidate_one(dentry, nd);
3587+
3588+ /*
3589+ * If __unionfs_d_revalidate_one() succeeded above, then it will
3590+ * have incremented the refcnt of the mnt's, but also the branch
3591+ * indices of the dentry will have been updated (to take into
3592+ * account any branch insertions/deletion. So the current
3593+ * dbstart/dbend match the current, and new, indices of the mnts
3594+ * which __unionfs_d_revalidate_one has incremented. Note: the "if"
3595+ * test below does not depend on whether chain_len was 0 or greater.
3596+ */
3597+ if (!valid || sbgen == dgen)
3598+ goto out;
3599+ for (bindex = dbstart(dentry); bindex <= dbend(dentry); bindex++)
3600+ unionfs_mntput(dentry, bindex);
3601+out:
3602+ return valid;
3603+}
3604+
3605+/*
3606+ * Revalidate a parent chain of dentries, then the actual node.
3607+ * Assumes that dentry is locked, but will lock all parents if/when needed.
3608+ *
3609+ * If 'willwrite' is true, and the lower inode times are not in sync, then
3610+ * *don't* purge_inode_data, as it could deadlock if ->write calls us and we
3611+ * try to truncate a locked page. Besides, if unionfs is about to write
3612+ * data to a file, then there's the data unionfs is about to write is more
3613+ * authoritative than what's below, therefore we can safely overwrite the
3614+ * lower inode times and data.
3615+ */
3616+bool __unionfs_d_revalidate_chain(struct dentry *dentry, struct nameidata *nd,
3617+ bool willwrite)
3618+{
3619+ bool valid = false; /* default is invalid */
3620+ struct dentry **chain = NULL; /* chain of dentries to reval */
3621+ int chain_len = 0;
3622+ struct dentry *dtmp;
3623+ int sbgen, dgen, i;
3624+ int saved_bstart, saved_bend, bindex;
3625+
3626+ /* find length of chain needed to revalidate */
3627+ /* XXX: should I grab some global (dcache?) lock? */
3628+ chain_len = 0;
3629+ sbgen = atomic_read(&UNIONFS_SB(dentry->d_sb)->generation);
3630+ dtmp = dentry->d_parent;
3631+ verify_locked(dentry);
3632+ if (dentry != dtmp)
3633+ unionfs_lock_dentry(dtmp, UNIONFS_DMUTEX_REVAL_PARENT);
3634+ dgen = atomic_read(&UNIONFS_D(dtmp)->generation);
3635+ /* XXX: should we check if is_newer_lower all the way up? */
3636+ if (unlikely(is_newer_lower(dtmp))) {
3637+ /*
3638+ * Special case: the root dentry's generation number must
3639+ * always be valid, but its lower inode times don't have to
3640+ * be, so sync up the times only.
3641+ */
3642+ if (IS_ROOT(dtmp)) {
3643+ unionfs_copy_attr_times(dtmp->d_inode);
3644+ } else {
3645+ /*
3646+ * reset generation number to zero, guaranteed to be
3647+ * "old"
3648+ */
3649+ dgen = 0;
3650+ atomic_set(&UNIONFS_D(dtmp)->generation, dgen);
3651+ }
3652+ purge_inode_data(dtmp->d_inode);
3653+ }
3654+ if (dentry != dtmp)
3655+ unionfs_unlock_dentry(dtmp);
3656+ while (sbgen != dgen) {
3657+ /* The root entry should always be valid */
3658+ BUG_ON(IS_ROOT(dtmp));
3659+ chain_len++;
3660+ dtmp = dtmp->d_parent;
3661+ dgen = atomic_read(&UNIONFS_D(dtmp)->generation);
3662+ }
3663+ if (chain_len == 0)
3664+ goto out_this; /* shortcut if parents are OK */
3665+
3666+ /*
3667+ * Allocate array of dentries to reval. We could use linked lists,
3668+ * but the number of entries we need to alloc here is often small,
3669+ * and short lived, so locality will be better.
3670+ */
3671+ chain = kzalloc(chain_len * sizeof(struct dentry *), GFP_KERNEL);
3672+ if (unlikely(!chain)) {
3673+ printk(KERN_CRIT "unionfs: no more memory in %s\n",
3674+ __func__);
3675+ goto out;
3676+ }
3677+
3678+ /* grab all dentries in chain, in child to parent order */
3679+ dtmp = dentry;
3680+ for (i = chain_len-1; i >= 0; i--)
3681+ dtmp = chain[i] = dget_parent(dtmp);
3682+
3683+ /*
3684+ * call __unionfs_d_revalidate_one() on each dentry, but in parent
3685+ * to child order.
3686+ */
3687+ for (i = 0; i < chain_len; i++) {
3688+ unionfs_lock_dentry(chain[i], UNIONFS_DMUTEX_REVAL_CHILD);
3689+ if (chain[i] != chain[i]->d_parent)
3690+ unionfs_lock_dentry(chain[i]->d_parent,
3691+ UNIONFS_DMUTEX_REVAL_PARENT);
3692+ saved_bstart = dbstart(chain[i]);
3693+ saved_bend = dbend(chain[i]);
3694+ sbgen = atomic_read(&UNIONFS_SB(dentry->d_sb)->generation);
3695+ dgen = atomic_read(&UNIONFS_D(chain[i])->generation);
3696+
3697+ valid = __unionfs_d_revalidate_one(chain[i], nd);
3698+ /* XXX: is this the correct mntput condition?! */
3699+ if (valid && chain_len > 0 &&
3700+ sbgen != dgen && chain[i]->d_inode &&
3701+ S_ISDIR(chain[i]->d_inode->i_mode)) {
3702+ for (bindex = saved_bstart; bindex <= saved_bend;
3703+ bindex++)
3704+ unionfs_mntput(chain[i], bindex);
3705+ }
3706+ if (chain[i] != chain[i]->d_parent)
3707+ unionfs_unlock_dentry(chain[i]->d_parent);
3708+ unionfs_unlock_dentry(chain[i]);
3709+
3710+ if (unlikely(!valid))
3711+ goto out_free;
3712+ }
3713+
3714+
3715+out_this:
3716+ /* finally, lock this dentry and revalidate it */
3717+ verify_locked(dentry); /* verify child is locked */
3718+ if (dentry != dentry->d_parent)
3719+ unionfs_lock_dentry(dentry->d_parent,
3720+ UNIONFS_DMUTEX_REVAL_PARENT);
3721+ valid = __unionfs_d_revalidate_one_locked(dentry, nd, willwrite);
3722+ if (dentry != dentry->d_parent)
3723+ unionfs_unlock_dentry(dentry->d_parent);
3724+
3725+out_free:
3726+ /* unlock/dput all dentries in chain and return status */
3727+ if (chain_len > 0) {
3728+ for (i = 0; i < chain_len; i++)
3729+ dput(chain[i]);
3730+ kfree(chain);
3731+ }
3732+out:
3733+ return valid;
3734+}
3735+
3736+static int unionfs_d_revalidate(struct dentry *dentry, struct nameidata *nd)
3737+{
3738+ int err;
3739+
3740+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD);
3741+
3742+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
3743+ err = __unionfs_d_revalidate_chain(dentry, nd, false);
3744+ if (likely(err > 0)) { /* true==1: dentry is valid */
3745+ unionfs_postcopyup_setmnt(dentry);
3746+ unionfs_check_dentry(dentry);
3747+ unionfs_check_nd(nd);
3748+ }
3749+ unionfs_unlock_dentry(dentry);
3750+
3751+ unionfs_read_unlock(dentry->d_sb);
3752+
3753+ return err;
3754+}
3755+
3756+static void unionfs_d_release(struct dentry *dentry)
3757+{
3758+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD);
3759+ if (unlikely(!UNIONFS_D(dentry)))
3760+ goto out; /* skip if no lower branches */
3761+ /* must lock our branch configuration here */
3762+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
3763+
3764+ unionfs_check_dentry(dentry);
3765+ /* this could be a negative dentry, so check first */
3766+ if (dbstart(dentry) < 0) {
3767+ unionfs_unlock_dentry(dentry);
3768+ goto out; /* due to a (normal) failed lookup */
3769+ }
3770+
3771+ /* Release all the lower dentries */
3772+ path_put_lowers_all(dentry, true);
3773+
3774+ unionfs_unlock_dentry(dentry);
3775+
3776+out:
3777+ free_dentry_private_data(dentry);
3778+ unionfs_read_unlock(dentry->d_sb);
3779+ return;
3780+}
3781+
3782+/*
3783+ * Called when we're removing the last reference to our dentry. So we
3784+ * should drop all lower references too.
3785+ */
3786+static void unionfs_d_iput(struct dentry *dentry, struct inode *inode)
3787+{
3788+ int rc;
3789+
3790+ BUG_ON(!dentry);
3791+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD);
3792+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
3793+
3794+ if (!UNIONFS_D(dentry) || dbstart(dentry) < 0)
3795+ goto drop_lower_inodes;
3796+ path_put_lowers_all(dentry, false);
3797+
3798+drop_lower_inodes:
3799+ rc = atomic_read(&inode->i_count);
3800+ if (rc == 1 && inode->i_nlink == 1 && ibstart(inode) >= 0) {
3801+ /* see Documentation/filesystems/unionfs/issues.txt */
3802+ lockdep_off();
3803+ iput(unionfs_lower_inode(inode));
3804+ lockdep_on();
3805+ unionfs_set_lower_inode(inode, NULL);
3806+ /* XXX: may need to set start/end to -1? */
3807+ }
3808+
3809+ iput(inode);
3810+
3811+ unionfs_unlock_dentry(dentry);
3812+ unionfs_read_unlock(dentry->d_sb);
3813+}
3814+
3815+struct dentry_operations unionfs_dops = {
3816+ .d_revalidate = unionfs_d_revalidate,
3817+ .d_release = unionfs_d_release,
3818+ .d_iput = unionfs_d_iput,
3819+};
3820diff --git a/fs/unionfs/dirfops.c b/fs/unionfs/dirfops.c
3821new file mode 100644
3822index 0000000..14ca7d3
3823--- /dev/null
3824+++ b/fs/unionfs/dirfops.c
3825@@ -0,0 +1,292 @@
3826+/*
3827+ * Copyright (c) 2003-2008 Erez Zadok
3828+ * Copyright (c) 2003-2006 Charles P. Wright
3829+ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
3830+ * Copyright (c) 2005-2006 Junjiro Okajima
3831+ * Copyright (c) 2005 Arun M. Krishnakumar
3832+ * Copyright (c) 2004-2006 David P. Quigley
3833+ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
3834+ * Copyright (c) 2003 Puja Gupta
3835+ * Copyright (c) 2003 Harikesavan Krishnan
3836+ * Copyright (c) 2003-2008 Stony Brook University
3837+ * Copyright (c) 2003-2008 The Research Foundation of SUNY
3838+ *
3839+ * This program is free software; you can redistribute it and/or modify
3840+ * it under the terms of the GNU General Public License version 2 as
3841+ * published by the Free Software Foundation.
3842+ */
3843+
3844+#include "union.h"
3845+
3846+/* Make sure our rdstate is playing by the rules. */
3847+static void verify_rdstate_offset(struct unionfs_dir_state *rdstate)
3848+{
3849+ BUG_ON(rdstate->offset >= DIREOF);
3850+ BUG_ON(rdstate->cookie >= MAXRDCOOKIE);
3851+}
3852+
3853+struct unionfs_getdents_callback {
3854+ struct unionfs_dir_state *rdstate;
3855+ void *dirent;
3856+ int entries_written;
3857+ int filldir_called;
3858+ int filldir_error;
3859+ filldir_t filldir;
3860+ struct super_block *sb;
3861+};
3862+
3863+/* based on generic filldir in fs/readir.c */
3864+static int unionfs_filldir(void *dirent, const char *oname, int namelen,
3865+ loff_t offset, u64 ino, unsigned int d_type)
3866+{
3867+ struct unionfs_getdents_callback *buf = dirent;
3868+ struct filldir_node *found = NULL;
3869+ int err = 0;
3870+ int is_whiteout;
3871+ char *name = (char *) oname;
3872+
3873+ buf->filldir_called++;
3874+
3875+ is_whiteout = is_whiteout_name(&name, &namelen);
3876+
3877+ found = find_filldir_node(buf->rdstate, name, namelen, is_whiteout);
3878+
3879+ if (found) {
3880+ /*
3881+ * If we had non-whiteout entry in dir cache, then mark it
3882+ * as a whiteout and but leave it in the dir cache.
3883+ */
3884+ if (is_whiteout && !found->whiteout)
3885+ found->whiteout = is_whiteout;
3886+ goto out;
3887+ }
3888+
3889+ /* if 'name' isn't a whiteout, filldir it. */
3890+ if (!is_whiteout) {
3891+ off_t pos = rdstate2offset(buf->rdstate);
3892+ u64 unionfs_ino = ino;
3893+
3894+ err = buf->filldir(buf->dirent, name, namelen, pos,
3895+ unionfs_ino, d_type);
3896+ buf->rdstate->offset++;
3897+ verify_rdstate_offset(buf->rdstate);
3898+ }
3899+ /*
3900+ * If we did fill it, stuff it in our hash, otherwise return an
3901+ * error.
3902+ */
3903+ if (err) {
3904+ buf->filldir_error = err;
3905+ goto out;
3906+ }
3907+ buf->entries_written++;
3908+ err = add_filldir_node(buf->rdstate, name, namelen,
3909+ buf->rdstate->bindex, is_whiteout);
3910+ if (err)
3911+ buf->filldir_error = err;
3912+
3913+out:
3914+ return err;
3915+}
3916+
3917+static int unionfs_readdir(struct file *file, void *dirent, filldir_t filldir)
3918+{
3919+ int err = 0;
3920+ struct file *lower_file = NULL;
3921+ struct dentry *dentry = file->f_path.dentry;
3922+ struct inode *inode = NULL;
3923+ struct unionfs_getdents_callback buf;
3924+ struct unionfs_dir_state *uds;
3925+ int bend;
3926+ loff_t offset;
3927+
3928+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_PARENT);
3929+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
3930+
3931+ err = unionfs_file_revalidate(file, false);
3932+ if (unlikely(err))
3933+ goto out;
3934+
3935+ inode = dentry->d_inode;
3936+
3937+ uds = UNIONFS_F(file)->rdstate;
3938+ if (!uds) {
3939+ if (file->f_pos == DIREOF) {
3940+ goto out;
3941+ } else if (file->f_pos > 0) {
3942+ uds = find_rdstate(inode, file->f_pos);
3943+ if (unlikely(!uds)) {
3944+ err = -ESTALE;
3945+ goto out;
3946+ }
3947+ UNIONFS_F(file)->rdstate = uds;
3948+ } else {
3949+ init_rdstate(file);
3950+ uds = UNIONFS_F(file)->rdstate;
3951+ }
3952+ }
3953+ bend = fbend(file);
3954+
3955+ while (uds->bindex <= bend) {
3956+ lower_file = unionfs_lower_file_idx(file, uds->bindex);
3957+ if (!lower_file) {
3958+ uds->bindex++;
3959+ uds->dirpos = 0;
3960+ continue;
3961+ }
3962+
3963+ /* prepare callback buffer */
3964+ buf.filldir_called = 0;
3965+ buf.filldir_error = 0;
3966+ buf.entries_written = 0;
3967+ buf.dirent = dirent;
3968+ buf.filldir = filldir;
3969+ buf.rdstate = uds;
3970+ buf.sb = inode->i_sb;
3971+
3972+ /* Read starting from where we last left off. */
3973+ offset = vfs_llseek(lower_file, uds->dirpos, SEEK_SET);
3974+ if (offset < 0) {
3975+ err = offset;
3976+ goto out;
3977+ }
3978+ err = vfs_readdir(lower_file, unionfs_filldir, &buf);
3979+
3980+ /* Save the position for when we continue. */
3981+ offset = vfs_llseek(lower_file, 0, SEEK_CUR);
3982+ if (offset < 0) {
3983+ err = offset;
3984+ goto out;
3985+ }
3986+ uds->dirpos = offset;
3987+
3988+ /* Copy the atime. */
3989+ fsstack_copy_attr_atime(inode,
3990+ lower_file->f_path.dentry->d_inode);
3991+
3992+ if (err < 0)
3993+ goto out;
3994+
3995+ if (buf.filldir_error)
3996+ break;
3997+
3998+ if (!buf.entries_written) {
3999+ uds->bindex++;
4000+ uds->dirpos = 0;
4001+ }
4002+ }
4003+
4004+ if (!buf.filldir_error && uds->bindex >= bend) {
4005+ /* Save the number of hash entries for next time. */
4006+ UNIONFS_I(inode)->hashsize = uds->hashentries;
4007+ free_rdstate(uds);
4008+ UNIONFS_F(file)->rdstate = NULL;
4009+ file->f_pos = DIREOF;
4010+ } else {
4011+ file->f_pos = rdstate2offset(uds);
4012+ }
4013+
4014+out:
4015+ unionfs_unlock_dentry(dentry);
4016+ unionfs_read_unlock(dentry->d_sb);
4017+ return err;
4018+}
4019+
4020+/*
4021+ * This is not meant to be a generic repositioning function. If you do
4022+ * things that aren't supported, then we return EINVAL.
4023+ *
4024+ * What is allowed:
4025+ * (1) seeking to the same position that you are currently at
4026+ * This really has no effect, but returns where you are.
4027+ * (2) seeking to the beginning of the file
4028+ * This throws out all state, and lets you begin again.
4029+ */
4030+static loff_t unionfs_dir_llseek(struct file *file, loff_t offset, int origin)
4031+{
4032+ struct unionfs_dir_state *rdstate;
4033+ struct dentry *dentry = file->f_path.dentry;
4034+ loff_t err;
4035+
4036+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_PARENT);
4037+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
4038+
4039+ err = unionfs_file_revalidate(file, false);
4040+ if (unlikely(err))
4041+ goto out;
4042+
4043+ rdstate = UNIONFS_F(file)->rdstate;
4044+
4045+ /*
4046+ * we let users seek to their current position, but not anywhere
4047+ * else.
4048+ */
4049+ if (!offset) {
4050+ switch (origin) {
4051+ case SEEK_SET:
4052+ if (rdstate) {
4053+ free_rdstate(rdstate);
4054+ UNIONFS_F(file)->rdstate = NULL;
4055+ }
4056+ init_rdstate(file);
4057+ err = 0;
4058+ break;
4059+ case SEEK_CUR:
4060+ err = file->f_pos;
4061+ break;
4062+ case SEEK_END:
4063+ /* Unsupported, because we would break everything. */
4064+ err = -EINVAL;
4065+ break;
4066+ }
4067+ } else {
4068+ switch (origin) {
4069+ case SEEK_SET:
4070+ if (rdstate) {
4071+ if (offset == rdstate2offset(rdstate))
4072+ err = offset;
4073+ else if (file->f_pos == DIREOF)
4074+ err = DIREOF;
4075+ else
4076+ err = -EINVAL;
4077+ } else {
4078+ struct inode *inode;
4079+ inode = dentry->d_inode;
4080+ rdstate = find_rdstate(inode, offset);
4081+ if (rdstate) {
4082+ UNIONFS_F(file)->rdstate = rdstate;
4083+ err = rdstate->offset;
4084+ } else {
4085+ err = -EINVAL;
4086+ }
4087+ }
4088+ break;
4089+ case SEEK_CUR:
4090+ case SEEK_END:
4091+ /* Unsupported, because we would break everything. */
4092+ err = -EINVAL;
4093+ break;
4094+ }
4095+ }
4096+
4097+out:
4098+ unionfs_unlock_dentry(dentry);
4099+ unionfs_read_unlock(dentry->d_sb);
4100+ return err;
4101+}
4102+
4103+/*
4104+ * Trimmed directory options, we shouldn't pass everything down since
4105+ * we don't want to operate on partial directories.
4106+ */
4107+struct file_operations unionfs_dir_fops = {
4108+ .llseek = unionfs_dir_llseek,
4109+ .read = generic_read_dir,
4110+ .readdir = unionfs_readdir,
4111+ .unlocked_ioctl = unionfs_ioctl,
4112+ .open = unionfs_open,
4113+ .release = unionfs_file_release,
4114+ .flush = unionfs_flush,
4115+ .fsync = unionfs_fsync,
4116+ .fasync = unionfs_fasync,
4117+};
4118diff --git a/fs/unionfs/dirhelper.c b/fs/unionfs/dirhelper.c
4119new file mode 100644
4120index 0000000..d936f03
4121--- /dev/null
4122+++ b/fs/unionfs/dirhelper.c
4123@@ -0,0 +1,157 @@
4124+/*
4125+ * Copyright (c) 2003-2008 Erez Zadok
4126+ * Copyright (c) 2003-2006 Charles P. Wright
4127+ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
4128+ * Copyright (c) 2005-2006 Junjiro Okajima
4129+ * Copyright (c) 2005 Arun M. Krishnakumar
4130+ * Copyright (c) 2004-2006 David P. Quigley
4131+ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
4132+ * Copyright (c) 2003 Puja Gupta
4133+ * Copyright (c) 2003 Harikesavan Krishnan
4134+ * Copyright (c) 2003-2008 Stony Brook University
4135+ * Copyright (c) 2003-2008 The Research Foundation of SUNY
4136+ *
4137+ * This program is free software; you can redistribute it and/or modify
4138+ * it under the terms of the GNU General Public License version 2 as
4139+ * published by the Free Software Foundation.
4140+ */
4141+
4142+#include "union.h"
4143+
4144+#define RD_NONE 0
4145+#define RD_CHECK_EMPTY 1
4146+/* The callback structure for check_empty. */
4147+struct unionfs_rdutil_callback {
4148+ int err;
4149+ int filldir_called;
4150+ struct unionfs_dir_state *rdstate;
4151+ int mode;
4152+};
4153+
4154+/* This filldir function makes sure only whiteouts exist within a directory. */
4155+static int readdir_util_callback(void *dirent, const char *oname, int namelen,
4156+ loff_t offset, u64 ino, unsigned int d_type)
4157+{
4158+ int err = 0;
4159+ struct unionfs_rdutil_callback *buf = dirent;
4160+ int is_whiteout;
4161+ struct filldir_node *found;
4162+ char *name = (char *) oname;
4163+
4164+ buf->filldir_called = 1;
4165+
4166+ if (name[0] == '.' && (namelen == 1 ||
4167+ (name[1] == '.' && namelen == 2)))
4168+ goto out;
4169+
4170+ is_whiteout = is_whiteout_name(&name, &namelen);
4171+
4172+ found = find_filldir_node(buf->rdstate, name, namelen, is_whiteout);
4173+ /* If it was found in the table there was a previous whiteout. */
4174+ if (found)
4175+ goto out;
4176+
4177+ /*
4178+ * if it wasn't found and isn't a whiteout, the directory isn't
4179+ * empty.
4180+ */
4181+ err = -ENOTEMPTY;
4182+ if ((buf->mode == RD_CHECK_EMPTY) && !is_whiteout)
4183+ goto out;
4184+
4185+ err = add_filldir_node(buf->rdstate, name, namelen,
4186+ buf->rdstate->bindex, is_whiteout);
4187+
4188+out:
4189+ buf->err = err;
4190+ return err;
4191+}
4192+
4193+/* Is a directory logically empty? */
4194+int check_empty(struct dentry *dentry, struct unionfs_dir_state **namelist)
4195+{
4196+ int err = 0;
4197+ struct dentry *lower_dentry = NULL;
4198+ struct vfsmount *mnt;
4199+ struct super_block *sb;
4200+ struct file *lower_file;
4201+ struct unionfs_rdutil_callback *buf = NULL;
4202+ int bindex, bstart, bend, bopaque;
4203+
4204+ sb = dentry->d_sb;
4205+
4206+
4207+ BUG_ON(!S_ISDIR(dentry->d_inode->i_mode));
4208+
4209+ err = unionfs_partial_lookup(dentry);
4210+ if (err)
4211+ goto out;
4212+
4213+ bstart = dbstart(dentry);
4214+ bend = dbend(dentry);
4215+ bopaque = dbopaque(dentry);
4216+ if (0 <= bopaque && bopaque < bend)
4217+ bend = bopaque;
4218+
4219+ buf = kmalloc(sizeof(struct unionfs_rdutil_callback), GFP_KERNEL);
4220+ if (unlikely(!buf)) {
4221+ err = -ENOMEM;
4222+ goto out;
4223+ }
4224+ buf->err = 0;
4225+ buf->mode = RD_CHECK_EMPTY;
4226+ buf->rdstate = alloc_rdstate(dentry->d_inode, bstart);
4227+ if (unlikely(!buf->rdstate)) {
4228+ err = -ENOMEM;
4229+ goto out;
4230+ }
4231+
4232+ /* Process the lower directories with rdutil_callback as a filldir. */
4233+ for (bindex = bstart; bindex <= bend; bindex++) {
4234+ lower_dentry = unionfs_lower_dentry_idx(dentry, bindex);
4235+ if (!lower_dentry)
4236+ continue;
4237+ if (!lower_dentry->d_inode)
4238+ continue;
4239+ if (!S_ISDIR(lower_dentry->d_inode->i_mode))
4240+ continue;
4241+
4242+ dget(lower_dentry);
4243+ mnt = unionfs_mntget(dentry, bindex);
4244+ branchget(sb, bindex);
4245+ lower_file = dentry_open(lower_dentry, mnt, O_RDONLY);
4246+ if (IS_ERR(lower_file)) {
4247+ err = PTR_ERR(lower_file);
4248+ branchput(sb, bindex);
4249+ goto out;
4250+ }
4251+
4252+ do {
4253+ buf->filldir_called = 0;
4254+ buf->rdstate->bindex = bindex;
4255+ err = vfs_readdir(lower_file,
4256+ readdir_util_callback, buf);
4257+ if (buf->err)
4258+ err = buf->err;
4259+ } while ((err >= 0) && buf->filldir_called);
4260+
4261+ /* fput calls dput for lower_dentry */
4262+ fput(lower_file);
4263+ branchput(sb, bindex);
4264+
4265+ if (err < 0)
4266+ goto out;
4267+ }
4268+
4269+out:
4270+ if (buf) {
4271+ if (namelist && !err)
4272+ *namelist = buf->rdstate;
4273+ else if (buf->rdstate)
4274+ free_rdstate(buf->rdstate);
4275+ kfree(buf);
4276+ }
4277+
4278+
4279+ return err;
4280+}
4281diff --git a/fs/unionfs/fanout.h b/fs/unionfs/fanout.h
4282new file mode 100644
4283index 0000000..4f264de
4284--- /dev/null
4285+++ b/fs/unionfs/fanout.h
4286@@ -0,0 +1,384 @@
4287+/*
4288+ * Copyright (c) 2003-2008 Erez Zadok
4289+ * Copyright (c) 2003-2006 Charles P. Wright
4290+ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
4291+ * Copyright (c) 2005 Arun M. Krishnakumar
4292+ * Copyright (c) 2004-2006 David P. Quigley
4293+ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
4294+ * Copyright (c) 2003 Puja Gupta
4295+ * Copyright (c) 2003 Harikesavan Krishnan
4296+ * Copyright (c) 2003-2008 Stony Brook University
4297+ * Copyright (c) 2003-2008 The Research Foundation of SUNY
4298+ *
4299+ * This program is free software; you can redistribute it and/or modify
4300+ * it under the terms of the GNU General Public License version 2 as
4301+ * published by the Free Software Foundation.
4302+ */
4303+
4304+#ifndef _FANOUT_H_
4305+#define _FANOUT_H_
4306+
4307+/*
4308+ * Inode to private data
4309+ *
4310+ * Since we use containers and the struct inode is _inside_ the
4311+ * unionfs_inode_info structure, UNIONFS_I will always (given a non-NULL
4312+ * inode pointer), return a valid non-NULL pointer.
4313+ */
4314+static inline struct unionfs_inode_info *UNIONFS_I(const struct inode *inode)
4315+{
4316+ return container_of(inode, struct unionfs_inode_info, vfs_inode);
4317+}
4318+
4319+#define ibstart(ino) (UNIONFS_I(ino)->bstart)
4320+#define ibend(ino) (UNIONFS_I(ino)->bend)
4321+
4322+/* Dentry to private data */
4323+#define UNIONFS_D(dent) ((struct unionfs_dentry_info *)(dent)->d_fsdata)
4324+#define dbstart(dent) (UNIONFS_D(dent)->bstart)
4325+#define dbend(dent) (UNIONFS_D(dent)->bend)
4326+#define dbopaque(dent) (UNIONFS_D(dent)->bopaque)
4327+
4328+/* Superblock to private data */
4329+#define UNIONFS_SB(super) ((struct unionfs_sb_info *)(super)->s_fs_info)
4330+#define sbstart(sb) 0
4331+#define sbend(sb) (UNIONFS_SB(sb)->bend)
4332+#define sbmax(sb) (UNIONFS_SB(sb)->bend + 1)
4333+#define sbhbid(sb) (UNIONFS_SB(sb)->high_branch_id)
4334+
4335+/* File to private Data */
4336+#define UNIONFS_F(file) ((struct unionfs_file_info *)((file)->private_data))
4337+#define fbstart(file) (UNIONFS_F(file)->bstart)
4338+#define fbend(file) (UNIONFS_F(file)->bend)
4339+
4340+/* macros to manipulate branch IDs in stored in our superblock */
4341+static inline int branch_id(struct super_block *sb, int index)
4342+{
4343+ BUG_ON(!sb || index < 0);
4344+ return UNIONFS_SB(sb)->data[index].branch_id;
4345+}
4346+
4347+static inline void set_branch_id(struct super_block *sb, int index, int val)
4348+{
4349+ BUG_ON(!sb || index < 0);
4350+ UNIONFS_SB(sb)->data[index].branch_id = val;
4351+}
4352+
4353+static inline void new_branch_id(struct super_block *sb, int index)
4354+{
4355+ BUG_ON(!sb || index < 0);
4356+ set_branch_id(sb, index, ++UNIONFS_SB(sb)->high_branch_id);
4357+}
4358+
4359+/*
4360+ * Find new index of matching branch with an existing superblock of a known
4361+ * (possibly old) id. This is needed because branches could have been
4362+ * added/deleted causing the branches of any open files to shift.
4363+ *
4364+ * @sb: the new superblock which may have new/different branch IDs
4365+ * @id: the old/existing id we're looking for
4366+ * Returns index of newly found branch (0 or greater), -1 otherwise.
4367+ */
4368+static inline int branch_id_to_idx(struct super_block *sb, int id)
4369+{
4370+ int i;
4371+ for (i = 0; i < sbmax(sb); i++) {
4372+ if (branch_id(sb, i) == id)
4373+ return i;
4374+ }
4375+ /* in the non-ODF code, this should really never happen */
4376+ printk(KERN_WARNING "unionfs: cannot find branch with id %d\n", id);
4377+ return -1;
4378+}
4379+
4380+/* File to lower file. */
4381+static inline struct file *unionfs_lower_file(const struct file *f)
4382+{
4383+ BUG_ON(!f);
4384+ return UNIONFS_F(f)->lower_files[fbstart(f)];
4385+}
4386+
4387+static inline struct file *unionfs_lower_file_idx(const struct file *f,
4388+ int index)
4389+{
4390+ BUG_ON(!f || index < 0);
4391+ return UNIONFS_F(f)->lower_files[index];
4392+}
4393+
4394+static inline void unionfs_set_lower_file_idx(struct file *f, int index,
4395+ struct file *val)
4396+{
4397+ BUG_ON(!f || index < 0);
4398+ UNIONFS_F(f)->lower_files[index] = val;
4399+ /* save branch ID (may be redundant?) */
4400+ UNIONFS_F(f)->saved_branch_ids[index] =
4401+ branch_id((f)->f_path.dentry->d_sb, index);
4402+}
4403+
4404+static inline void unionfs_set_lower_file(struct file *f, struct file *val)
4405+{
4406+ BUG_ON(!f);
4407+ unionfs_set_lower_file_idx((f), fbstart(f), (val));
4408+}
4409+
4410+/* Inode to lower inode. */
4411+static inline struct inode *unionfs_lower_inode(const struct inode *i)
4412+{
4413+ BUG_ON(!i);
4414+ return UNIONFS_I(i)->lower_inodes[ibstart(i)];
4415+}
4416+
4417+static inline struct inode *unionfs_lower_inode_idx(const struct inode *i,
4418+ int index)
4419+{
4420+ BUG_ON(!i || index < 0);
4421+ return UNIONFS_I(i)->lower_inodes[index];
4422+}
4423+
4424+static inline void unionfs_set_lower_inode_idx(struct inode *i, int index,
4425+ struct inode *val)
4426+{
4427+ BUG_ON(!i || index < 0);
4428+ UNIONFS_I(i)->lower_inodes[index] = val;
4429+}
4430+
4431+static inline void unionfs_set_lower_inode(struct inode *i, struct inode *val)
4432+{
4433+ BUG_ON(!i);
4434+ UNIONFS_I(i)->lower_inodes[ibstart(i)] = val;
4435+}
4436+
4437+/* Superblock to lower superblock. */
4438+static inline struct super_block *unionfs_lower_super(
4439+ const struct super_block *sb)
4440+{
4441+ BUG_ON(!sb);
4442+ return UNIONFS_SB(sb)->data[sbstart(sb)].sb;
4443+}
4444+
4445+static inline struct super_block *unionfs_lower_super_idx(
4446+ const struct super_block *sb,
4447+ int index)
4448+{
4449+ BUG_ON(!sb || index < 0);
4450+ return UNIONFS_SB(sb)->data[index].sb;
4451+}
4452+
4453+static inline void unionfs_set_lower_super_idx(struct super_block *sb,
4454+ int index,
4455+ struct super_block *val)
4456+{
4457+ BUG_ON(!sb || index < 0);
4458+ UNIONFS_SB(sb)->data[index].sb = val;
4459+}
4460+
4461+static inline void unionfs_set_lower_super(struct super_block *sb,
4462+ struct super_block *val)
4463+{
4464+ BUG_ON(!sb);
4465+ UNIONFS_SB(sb)->data[sbstart(sb)].sb = val;
4466+}
4467+
4468+/* Branch count macros. */
4469+static inline int branch_count(const struct super_block *sb, int index)
4470+{
4471+ BUG_ON(!sb || index < 0);
4472+ return atomic_read(&UNIONFS_SB(sb)->data[index].open_files);
4473+}
4474+
4475+static inline void set_branch_count(struct super_block *sb, int index, int val)
4476+{
4477+ BUG_ON(!sb || index < 0);
4478+ atomic_set(&UNIONFS_SB(sb)->data[index].open_files, val);
4479+}
4480+
4481+static inline void branchget(struct super_block *sb, int index)
4482+{
4483+ BUG_ON(!sb || index < 0);
4484+ atomic_inc(&UNIONFS_SB(sb)->data[index].open_files);
4485+}
4486+
4487+static inline void branchput(struct super_block *sb, int index)
4488+{
4489+ BUG_ON(!sb || index < 0);
4490+ atomic_dec(&UNIONFS_SB(sb)->data[index].open_files);
4491+}
4492+
4493+/* Dentry macros */
4494+static inline void unionfs_set_lower_dentry_idx(struct dentry *dent, int index,
4495+ struct dentry *val)
4496+{
4497+ BUG_ON(!dent || index < 0);
4498+ UNIONFS_D(dent)->lower_paths[index].dentry = val;
4499+}
4500+
4501+static inline struct dentry *unionfs_lower_dentry_idx(
4502+ const struct dentry *dent,
4503+ int index)
4504+{
4505+ BUG_ON(!dent || index < 0);
4506+ return UNIONFS_D(dent)->lower_paths[index].dentry;
4507+}
4508+
4509+static inline struct dentry *unionfs_lower_dentry(const struct dentry *dent)
4510+{
4511+ BUG_ON(!dent);
4512+ return unionfs_lower_dentry_idx(dent, dbstart(dent));
4513+}
4514+
4515+static inline void unionfs_set_lower_mnt_idx(struct dentry *dent, int index,
4516+ struct vfsmount *mnt)
4517+{
4518+ BUG_ON(!dent || index < 0);
4519+ UNIONFS_D(dent)->lower_paths[index].mnt = mnt;
4520+}
4521+
4522+static inline struct vfsmount *unionfs_lower_mnt_idx(
4523+ const struct dentry *dent,
4524+ int index)
4525+{
4526+ BUG_ON(!dent || index < 0);
4527+ return UNIONFS_D(dent)->lower_paths[index].mnt;
4528+}
4529+
4530+static inline struct vfsmount *unionfs_lower_mnt(const struct dentry *dent)
4531+{
4532+ BUG_ON(!dent);
4533+ return unionfs_lower_mnt_idx(dent, dbstart(dent));
4534+}
4535+
4536+/* Macros for locking a dentry. */
4537+enum unionfs_dentry_lock_class {
4538+ UNIONFS_DMUTEX_NORMAL,
4539+ UNIONFS_DMUTEX_ROOT,
4540+ UNIONFS_DMUTEX_PARENT,
4541+ UNIONFS_DMUTEX_CHILD,
4542+ UNIONFS_DMUTEX_WHITEOUT,
4543+ UNIONFS_DMUTEX_REVAL_PARENT, /* for file/dentry revalidate */
4544+ UNIONFS_DMUTEX_REVAL_CHILD, /* for file/dentry revalidate */
4545+};
4546+
4547+static inline void unionfs_lock_dentry(struct dentry *d,
4548+ unsigned int subclass)
4549+{
4550+ BUG_ON(!d);
4551+ mutex_lock_nested(&UNIONFS_D(d)->lock, subclass);
4552+}
4553+
4554+static inline void unionfs_unlock_dentry(struct dentry *d)
4555+{
4556+ BUG_ON(!d);
4557+ mutex_unlock(&UNIONFS_D(d)->lock);
4558+}
4559+
4560+static inline void verify_locked(struct dentry *d)
4561+{
4562+ BUG_ON(!d);
4563+ BUG_ON(!mutex_is_locked(&UNIONFS_D(d)->lock));
4564+}
4565+
4566+/* macros to put lower objects */
4567+
4568+/*
4569+ * iput lower inodes of an unionfs dentry, from bstart to bend. If
4570+ * @free_lower is true, then also kfree the memory used to hold the lower
4571+ * object pointers.
4572+ */
4573+static inline void iput_lowers(struct inode *inode,
4574+ int bstart, int bend, bool free_lower)
4575+{
4576+ struct inode *lower_inode;
4577+ int bindex;
4578+
4579+ BUG_ON(!inode);
4580+ BUG_ON(!UNIONFS_I(inode));
4581+ BUG_ON(bstart < 0);
4582+
4583+ for (bindex = bstart; bindex <= bend; bindex++) {
4584+ lower_inode = unionfs_lower_inode_idx(inode, bindex);
4585+ if (lower_inode) {
4586+ unionfs_set_lower_inode_idx(inode, bindex, NULL);
4587+ /* see Documentation/filesystems/unionfs/issues.txt */
4588+ lockdep_off();
4589+ iput(lower_inode);
4590+ lockdep_on();
4591+ }
4592+ }
4593+
4594+ if (free_lower) {
4595+ kfree(UNIONFS_I(inode)->lower_inodes);
4596+ UNIONFS_I(inode)->lower_inodes = NULL;
4597+ }
4598+}
4599+
4600+/* iput all lower inodes, and reset start/end branch indices to -1 */
4601+static inline void iput_lowers_all(struct inode *inode, bool free_lower)
4602+{
4603+ int bstart, bend;
4604+
4605+ BUG_ON(!inode);
4606+ BUG_ON(!UNIONFS_I(inode));
4607+ bstart = ibstart(inode);
4608+ bend = ibend(inode);
4609+ BUG_ON(bstart < 0);
4610+
4611+ iput_lowers(inode, bstart, bend, free_lower);
4612+ ibstart(inode) = ibend(inode) = -1;
4613+}
4614+
4615+/*
4616+ * dput/mntput all lower dentries and vfsmounts of an unionfs dentry, from
4617+ * bstart to bend. If @free_lower is true, then also kfree the memory used
4618+ * to hold the lower object pointers.
4619+ *
4620+ * XXX: implement using path_put VFS macros
4621+ */
4622+static inline void path_put_lowers(struct dentry *dentry,
4623+ int bstart, int bend, bool free_lower)
4624+{
4625+ struct dentry *lower_dentry;
4626+ struct vfsmount *lower_mnt;
4627+ int bindex;
4628+
4629+ BUG_ON(!dentry);
4630+ BUG_ON(!UNIONFS_D(dentry));
4631+ BUG_ON(bstart < 0);
4632+
4633+ for (bindex = bstart; bindex <= bend; bindex++) {
4634+ lower_dentry = unionfs_lower_dentry_idx(dentry, bindex);
4635+ if (lower_dentry) {
4636+ unionfs_set_lower_dentry_idx(dentry, bindex, NULL);
4637+ dput(lower_dentry);
4638+ }
4639+ lower_mnt = unionfs_lower_mnt_idx(dentry, bindex);
4640+ if (lower_mnt) {
4641+ unionfs_set_lower_mnt_idx(dentry, bindex, NULL);
4642+ mntput(lower_mnt);
4643+ }
4644+ }
4645+
4646+ if (free_lower) {
4647+ kfree(UNIONFS_D(dentry)->lower_paths);
4648+ UNIONFS_D(dentry)->lower_paths = NULL;
4649+ }
4650+}
4651+
4652+/*
4653+ * dput/mntput all lower dentries and vfsmounts, and reset start/end branch
4654+ * indices to -1.
4655+ */
4656+static inline void path_put_lowers_all(struct dentry *dentry, bool free_lower)
4657+{
4658+ int bstart, bend;
4659+
4660+ BUG_ON(!dentry);
4661+ BUG_ON(!UNIONFS_D(dentry));
4662+ bstart = dbstart(dentry);
4663+ bend = dbend(dentry);
4664+ BUG_ON(bstart < 0);
4665+
4666+ path_put_lowers(dentry, bstart, bend, free_lower);
4667+ dbstart(dentry) = dbend(dentry) = -1;
4668+}
4669+
4670+#endif /* not _FANOUT_H */
4671diff --git a/fs/unionfs/file.c b/fs/unionfs/file.c
4672new file mode 100644
4673index 0000000..965d071
4674--- /dev/null
4675+++ b/fs/unionfs/file.c
4676@@ -0,0 +1,341 @@
4677+/*
4678+ * Copyright (c) 2003-2008 Erez Zadok
4679+ * Copyright (c) 2003-2006 Charles P. Wright
4680+ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
4681+ * Copyright (c) 2005-2006 Junjiro Okajima
4682+ * Copyright (c) 2005 Arun M. Krishnakumar
4683+ * Copyright (c) 2004-2006 David P. Quigley
4684+ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
4685+ * Copyright (c) 2003 Puja Gupta
4686+ * Copyright (c) 2003 Harikesavan Krishnan
4687+ * Copyright (c) 2003-2008 Stony Brook University
4688+ * Copyright (c) 2003-2008 The Research Foundation of SUNY
4689+ *
4690+ * This program is free software; you can redistribute it and/or modify
4691+ * it under the terms of the GNU General Public License version 2 as
4692+ * published by the Free Software Foundation.
4693+ */
4694+
4695+#include "union.h"
4696+
4697+static ssize_t unionfs_read(struct file *file, char __user *buf,
4698+ size_t count, loff_t *ppos)
4699+{
4700+ int err;
4701+ struct file *lower_file;
4702+ struct dentry *dentry = file->f_path.dentry;
4703+
4704+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_PARENT);
4705+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
4706+ err = unionfs_file_revalidate(file, false);
4707+ if (unlikely(err))
4708+ goto out;
4709+
4710+ lower_file = unionfs_lower_file(file);
4711+ err = vfs_read(lower_file, buf, count, ppos);
4712+ /* update our inode atime upon a successful lower read */
4713+ if (err >= 0) {
4714+ fsstack_copy_attr_atime(dentry->d_inode,
4715+ lower_file->f_path.dentry->d_inode);
4716+ unionfs_check_file(file);
4717+ }
4718+
4719+out:
4720+ unionfs_unlock_dentry(dentry);
4721+ unionfs_read_unlock(dentry->d_sb);
4722+ return err;
4723+}
4724+
4725+static ssize_t unionfs_write(struct file *file, const char __user *buf,
4726+ size_t count, loff_t *ppos)
4727+{
4728+ int err = 0;
4729+ struct file *lower_file;
4730+ struct dentry *dentry = file->f_path.dentry;
4731+
4732+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_PARENT);
4733+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
4734+ if (dentry != dentry->d_parent)
4735+ unionfs_lock_dentry(dentry->d_parent, UNIONFS_DMUTEX_PARENT);
4736+ err = unionfs_file_revalidate_locked(file, true);
4737+ if (unlikely(err))
4738+ goto out;
4739+
4740+ lower_file = unionfs_lower_file(file);
4741+ err = vfs_write(lower_file, buf, count, ppos);
4742+ /* update our inode times+sizes upon a successful lower write */
4743+ if (err >= 0) {
4744+ fsstack_copy_inode_size(dentry->d_inode,
4745+ lower_file->f_path.dentry->d_inode);
4746+ fsstack_copy_attr_times(dentry->d_inode,
4747+ lower_file->f_path.dentry->d_inode);
4748+ UNIONFS_F(file)->wrote_to_file = true; /* for delayed copyup */
4749+ unionfs_check_file(file);
4750+ }
4751+
4752+out:
4753+ if (dentry != dentry->d_parent)
4754+ unionfs_unlock_dentry(dentry->d_parent);
4755+ unionfs_unlock_dentry(dentry);
4756+ unionfs_read_unlock(dentry->d_sb);
4757+ return err;
4758+}
4759+
4760+static int unionfs_file_readdir(struct file *file, void *dirent,
4761+ filldir_t filldir)
4762+{
4763+ return -ENOTDIR;
4764+}
4765+
4766+static int unionfs_mmap(struct file *file, struct vm_area_struct *vma)
4767+{
4768+ int err = 0;
4769+ bool willwrite;
4770+ struct file *lower_file;
4771+ struct dentry *dentry = file->f_path.dentry;
4772+ struct vm_operations_struct *saved_vm_ops = NULL;
4773+
4774+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_PARENT);
4775+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
4776+
4777+ /* This might be deferred to mmap's writepage */
4778+ willwrite = ((vma->vm_flags | VM_SHARED | VM_WRITE) == vma->vm_flags);
4779+ err = unionfs_file_revalidate(file, willwrite);
4780+ if (unlikely(err))
4781+ goto out;
4782+ unionfs_check_file(file);
4783+
4784+ /*
4785+ * File systems which do not implement ->writepage may use
4786+ * generic_file_readonly_mmap as their ->mmap op. If you call
4787+ * generic_file_readonly_mmap with VM_WRITE, you'd get an -EINVAL.
4788+ * But we cannot call the lower ->mmap op, so we can't tell that
4789+ * writeable mappings won't work. Therefore, our only choice is to
4790+ * check if the lower file system supports the ->writepage, and if
4791+ * not, return EINVAL (the same error that
4792+ * generic_file_readonly_mmap returns in that case).
4793+ */
4794+ lower_file = unionfs_lower_file(file);
4795+ if (willwrite && !lower_file->f_mapping->a_ops->writepage) {
4796+ err = -EINVAL;
4797+ printk(KERN_ERR "unionfs: branch %d file system does not "
4798+ "support writeable mmap\n", fbstart(file));
4799+ goto out;
4800+ }
4801+
4802+ /*
4803+ * find and save lower vm_ops.
4804+ *
4805+ * XXX: the VFS should have a cleaner way of finding the lower vm_ops
4806+ */
4807+ if (!UNIONFS_F(file)->lower_vm_ops) {
4808+ err = lower_file->f_op->mmap(lower_file, vma);
4809+ if (err) {
4810+ printk(KERN_ERR "unionfs: lower mmap failed %d\n", err);
4811+ goto out;
4812+ }
4813+ saved_vm_ops = vma->vm_ops;
4814+ err = do_munmap(current->mm, vma->vm_start,
4815+ vma->vm_end - vma->vm_start);
4816+ if (err) {
4817+ printk(KERN_ERR "unionfs: do_munmap failed %d\n", err);
4818+ goto out;
4819+ }
4820+ }
4821+
4822+ file->f_mapping->a_ops = &unionfs_dummy_aops;
4823+ err = generic_file_mmap(file, vma);
4824+ file->f_mapping->a_ops = &unionfs_aops;
4825+ if (err) {
4826+ printk(KERN_ERR "unionfs: generic_file_mmap failed %d\n", err);
4827+ goto out;
4828+ }
4829+ vma->vm_ops = &unionfs_vm_ops;
4830+ if (!UNIONFS_F(file)->lower_vm_ops)
4831+ UNIONFS_F(file)->lower_vm_ops = saved_vm_ops;
4832+
4833+out:
4834+ if (!err) {
4835+ /* copyup could cause parent dir times to change */
4836+ unionfs_copy_attr_times(dentry->d_parent->d_inode);
4837+ unionfs_check_file(file);
4838+ }
4839+ unionfs_unlock_dentry(dentry);
4840+ unionfs_read_unlock(dentry->d_sb);
4841+ return err;
4842+}
4843+
4844+int unionfs_fsync(struct file *file, struct dentry *dentry, int datasync)
4845+{
4846+ int bindex, bstart, bend;
4847+ struct file *lower_file;
4848+ struct dentry *lower_dentry;
4849+ struct inode *lower_inode, *inode;
4850+ int err = -EINVAL;
4851+
4852+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_PARENT);
4853+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
4854+ err = unionfs_file_revalidate(file, true);
4855+ if (unlikely(err))
4856+ goto out;
4857+ unionfs_check_file(file);
4858+
4859+ bstart = fbstart(file);
4860+ bend = fbend(file);
4861+ if (bstart < 0 || bend < 0)
4862+ goto out;
4863+
4864+ inode = dentry->d_inode;
4865+ if (unlikely(!inode)) {
4866+ printk(KERN_ERR
4867+ "unionfs: null lower inode in unionfs_fsync\n");
4868+ goto out;
4869+ }
4870+ for (bindex = bstart; bindex <= bend; bindex++) {
4871+ lower_inode = unionfs_lower_inode_idx(inode, bindex);
4872+ if (!lower_inode || !lower_inode->i_fop->fsync)
4873+ continue;
4874+ lower_file = unionfs_lower_file_idx(file, bindex);
4875+ lower_dentry = unionfs_lower_dentry_idx(dentry, bindex);
4876+ mutex_lock(&lower_inode->i_mutex);
4877+ err = lower_inode->i_fop->fsync(lower_file,
4878+ lower_dentry,
4879+ datasync);
4880+ if (!err && bindex == bstart)
4881+ fsstack_copy_attr_times(inode, lower_inode);
4882+ mutex_unlock(&lower_inode->i_mutex);
4883+ if (err)
4884+ goto out;
4885+ }
4886+
4887+out:
4888+ if (!err)
4889+ unionfs_check_file(file);
4890+ unionfs_unlock_dentry(dentry);
4891+ unionfs_read_unlock(dentry->d_sb);
4892+ return err;
4893+}
4894+
4895+int unionfs_fasync(int fd, struct file *file, int flag)
4896+{
4897+ int bindex, bstart, bend;
4898+ struct file *lower_file;
4899+ struct dentry *dentry = file->f_path.dentry;
4900+ struct inode *lower_inode, *inode;
4901+ int err = 0;
4902+
4903+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_PARENT);
4904+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
4905+ err = unionfs_file_revalidate(file, true);
4906+ if (unlikely(err))
4907+ goto out;
4908+ unionfs_check_file(file);
4909+
4910+ bstart = fbstart(file);
4911+ bend = fbend(file);
4912+ if (bstart < 0 || bend < 0)
4913+ goto out;
4914+
4915+ inode = dentry->d_inode;
4916+ if (unlikely(!inode)) {
4917+ printk(KERN_ERR
4918+ "unionfs: null lower inode in unionfs_fasync\n");
4919+ goto out;
4920+ }
4921+ for (bindex = bstart; bindex <= bend; bindex++) {
4922+ lower_inode = unionfs_lower_inode_idx(inode, bindex);
4923+ if (!lower_inode || !lower_inode->i_fop->fasync)
4924+ continue;
4925+ lower_file = unionfs_lower_file_idx(file, bindex);
4926+ mutex_lock(&lower_inode->i_mutex);
4927+ err = lower_inode->i_fop->fasync(fd, lower_file, flag);
4928+ if (!err && bindex == bstart)
4929+ fsstack_copy_attr_times(inode, lower_inode);
4930+ mutex_unlock(&lower_inode->i_mutex);
4931+ if (err)
4932+ goto out;
4933+ }
4934+
4935+out:
4936+ if (!err)
4937+ unionfs_check_file(file);
4938+ unionfs_unlock_dentry(dentry);
4939+ unionfs_read_unlock(dentry->d_sb);
4940+ return err;
4941+}
4942+
4943+static ssize_t unionfs_splice_read(struct file *file, loff_t *ppos,
4944+ struct pipe_inode_info *pipe, size_t len,
4945+ unsigned int flags)
4946+{
4947+ ssize_t err;
4948+ struct file *lower_file;
4949+ struct dentry *dentry = file->f_path.dentry;
4950+
4951+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_PARENT);
4952+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
4953+ err = unionfs_file_revalidate(file, false);
4954+ if (unlikely(err))
4955+ goto out;
4956+
4957+ lower_file = unionfs_lower_file(file);
4958+ err = vfs_splice_to(lower_file, ppos, pipe, len, flags);
4959+ /* update our inode atime upon a successful lower splice-read */
4960+ if (err >= 0) {
4961+ fsstack_copy_attr_atime(dentry->d_inode,
4962+ lower_file->f_path.dentry->d_inode);
4963+ unionfs_check_file(file);
4964+ }
4965+
4966+out:
4967+ unionfs_unlock_dentry(dentry);
4968+ unionfs_read_unlock(dentry->d_sb);
4969+ return err;
4970+}
4971+
4972+static ssize_t unionfs_splice_write(struct pipe_inode_info *pipe,
4973+ struct file *file, loff_t *ppos,
4974+ size_t len, unsigned int flags)
4975+{
4976+ ssize_t err = 0;
4977+ struct file *lower_file;
4978+ struct dentry *dentry = file->f_path.dentry;
4979+
4980+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_PARENT);
4981+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
4982+ err = unionfs_file_revalidate(file, true);
4983+ if (unlikely(err))
4984+ goto out;
4985+
4986+ lower_file = unionfs_lower_file(file);
4987+ err = vfs_splice_from(pipe, lower_file, ppos, len, flags);
4988+ /* update our inode times+sizes upon a successful lower write */
4989+ if (err >= 0) {
4990+ fsstack_copy_inode_size(dentry->d_inode,
4991+ lower_file->f_path.dentry->d_inode);
4992+ fsstack_copy_attr_times(dentry->d_inode,
4993+ lower_file->f_path.dentry->d_inode);
4994+ unionfs_check_file(file);
4995+ }
4996+
4997+out:
4998+ unionfs_unlock_dentry(dentry);
4999+ unionfs_read_unlock(dentry->d_sb);
5000+ return err;
5001+}
5002+
5003+struct file_operations unionfs_main_fops = {
5004+ .llseek = generic_file_llseek,
5005+ .read = unionfs_read,
5006+ .write = unionfs_write,
5007+ .readdir = unionfs_file_readdir,
5008+ .unlocked_ioctl = unionfs_ioctl,
5009+ .mmap = unionfs_mmap,
5010+ .open = unionfs_open,
5011+ .flush = unionfs_flush,
5012+ .release = unionfs_file_release,
5013+ .fsync = unionfs_fsync,
5014+ .fasync = unionfs_fasync,
5015+ .splice_read = unionfs_splice_read,
5016+ .splice_write = unionfs_splice_write,
5017+};
5018diff --git a/fs/unionfs/inode.c b/fs/unionfs/inode.c
5019new file mode 100644
5020index 0000000..0bd9fab
5021--- /dev/null
5022+++ b/fs/unionfs/inode.c
5023@@ -0,0 +1,984 @@
5024+/*
5025+ * Copyright (c) 2003-2008 Erez Zadok
5026+ * Copyright (c) 2003-2006 Charles P. Wright
5027+ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
5028+ * Copyright (c) 2005-2006 Junjiro Okajima
5029+ * Copyright (c) 2005 Arun M. Krishnakumar
5030+ * Copyright (c) 2004-2006 David P. Quigley
5031+ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
5032+ * Copyright (c) 2003 Puja Gupta
5033+ * Copyright (c) 2003 Harikesavan Krishnan
5034+ * Copyright (c) 2003-2008 Stony Brook University
5035+ * Copyright (c) 2003-2008 The Research Foundation of SUNY
5036+ *
5037+ * This program is free software; you can redistribute it and/or modify
5038+ * it under the terms of the GNU General Public License version 2 as
5039+ * published by the Free Software Foundation.
5040+ */
5041+
5042+#include "union.h"
5043+
5044+/*
5045+ * Find a writeable branch to create new object in. Checks all writeble
5046+ * branches of the parent inode, from istart to iend order; if none are
5047+ * suitable, also tries branch 0 (which may require a copyup).
5048+ *
5049+ * Return a lower_dentry we can use to create object in, or ERR_PTR.
5050+ */
5051+static struct dentry *find_writeable_branch(struct inode *parent,
5052+ struct dentry *dentry)
5053+{
5054+ int err = -EINVAL;
5055+ int bindex, istart, iend;
5056+ struct dentry *lower_dentry = NULL;
5057+
5058+ istart = ibstart(parent);
5059+ iend = ibend(parent);
5060+ if (istart < 0)
5061+ goto out;
5062+
5063+begin:
5064+ for (bindex = istart; bindex <= iend; bindex++) {
5065+ /* skip non-writeable branches */
5066+ err = is_robranch_super(dentry->d_sb, bindex);
5067+ if (err) {
5068+ err = -EROFS;
5069+ continue;
5070+ }
5071+ lower_dentry = unionfs_lower_dentry_idx(dentry, bindex);
5072+ if (!lower_dentry)
5073+ continue;
5074+ /*
5075+ * check for whiteouts in writeable branch, and remove them
5076+ * if necessary.
5077+ */
5078+ err = check_unlink_whiteout(dentry, lower_dentry, bindex);
5079+ if (err > 0) /* ignore if whiteout found and removed */
5080+ err = 0;
5081+ if (err)
5082+ continue;
5083+ /* if get here, we can write to the branch */
5084+ break;
5085+ }
5086+ /*
5087+ * If istart wasn't already branch 0, and we got any error, then try
5088+ * branch 0 (which may require copyup)
5089+ */
5090+ if (err && istart > 0) {
5091+ istart = iend = 0;
5092+ goto begin;
5093+ }
5094+
5095+ /*
5096+ * If we tried even branch 0, and still got an error, abort. But if
5097+ * the error was an EROFS, then we should try to copyup.
5098+ */
5099+ if (err && err != -EROFS)
5100+ goto out;
5101+
5102+ /*
5103+ * If we get here, then check if copyup needed. If lower_dentry is
5104+ * NULL, create the entire dentry directory structure in branch 0.
5105+ */
5106+ if (!lower_dentry) {
5107+ bindex = 0;
5108+ lower_dentry = create_parents(parent, dentry,
5109+ dentry->d_name.name, bindex);
5110+ if (IS_ERR(lower_dentry)) {
5111+ err = PTR_ERR(lower_dentry);
5112+ goto out;
5113+ }
5114+ }
5115+ err = 0; /* all's well */
5116+out:
5117+ if (err)
5118+ return ERR_PTR(err);
5119+ return lower_dentry;
5120+}
5121+
5122+static int unionfs_create(struct inode *parent, struct dentry *dentry,
5123+ int mode, struct nameidata *nd)
5124+{
5125+ int err = 0;
5126+ struct dentry *lower_dentry = NULL;
5127+ struct dentry *lower_parent_dentry = NULL;
5128+ int valid = 0;
5129+ struct nameidata lower_nd;
5130+
5131+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD);
5132+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
5133+ unionfs_lock_dentry(dentry->d_parent, UNIONFS_DMUTEX_PARENT);
5134+
5135+ valid = __unionfs_d_revalidate_chain(dentry->d_parent, nd, false);
5136+ if (unlikely(!valid)) {
5137+ err = -ESTALE; /* same as what real_lookup does */
5138+ goto out;
5139+ }
5140+
5141+ valid = __unionfs_d_revalidate_one_locked(dentry, nd, false);
5142+ /*
5143+ * It's only a bug if this dentry was not negative and couldn't be
5144+ * revalidated (shouldn't happen).
5145+ */
5146+ BUG_ON(!valid && dentry->d_inode);
5147+
5148+ lower_dentry = find_writeable_branch(parent, dentry);
5149+ if (IS_ERR(lower_dentry)) {
5150+ err = PTR_ERR(lower_dentry);
5151+ goto out;
5152+ }
5153+
5154+ lower_parent_dentry = lock_parent(lower_dentry);
5155+ if (IS_ERR(lower_parent_dentry)) {
5156+ err = PTR_ERR(lower_parent_dentry);
5157+ goto out;
5158+ }
5159+
5160+ err = init_lower_nd(&lower_nd, LOOKUP_CREATE);
5161+ if (unlikely(err < 0))
5162+ goto out;
5163+ err = vfs_create(lower_parent_dentry->d_inode, lower_dentry, mode,
5164+ &lower_nd);
5165+ release_lower_nd(&lower_nd, err);
5166+
5167+ if (!err) {
5168+ err = PTR_ERR(unionfs_interpose(dentry, parent->i_sb, 0));
5169+ if (!err) {
5170+ unionfs_copy_attr_times(parent);
5171+ fsstack_copy_inode_size(parent,
5172+ lower_parent_dentry->d_inode);
5173+ /* update no. of links on parent directory */
5174+ parent->i_nlink = unionfs_get_nlinks(parent);
5175+ }
5176+ }
5177+
5178+ unlock_dir(lower_parent_dentry);
5179+
5180+out:
5181+ if (!err) {
5182+ unionfs_postcopyup_setmnt(dentry);
5183+ unionfs_check_inode(parent);
5184+ unionfs_check_dentry(dentry);
5185+ unionfs_check_nd(nd);
5186+ }
5187+ unionfs_unlock_dentry(dentry->d_parent);
5188+ unionfs_unlock_dentry(dentry);
5189+ unionfs_read_unlock(dentry->d_sb);
5190+ return err;
5191+}
5192+
5193+/*
5194+ * unionfs_lookup is the only special function which takes a dentry, yet we
5195+ * do NOT want to call __unionfs_d_revalidate_chain because by definition,
5196+ * we don't have a valid dentry here yet.
5197+ */
5198+static struct dentry *unionfs_lookup(struct inode *parent,
5199+ struct dentry *dentry,
5200+ struct nameidata *nd)
5201+{
5202+ struct path path_save = {NULL, NULL};
5203+ struct dentry *ret;
5204+ int err = 0;
5205+
5206+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD);
5207+ if (dentry != dentry->d_parent)
5208+ unionfs_lock_dentry(dentry->d_parent, UNIONFS_DMUTEX_ROOT);
5209+
5210+ /* save the dentry & vfsmnt from namei */
5211+ if (nd) {
5212+ path_save.dentry = nd->path.dentry;
5213+ path_save.mnt = nd->path.mnt;
5214+ }
5215+
5216+ /*
5217+ * unionfs_lookup_backend returns a locked dentry upon success,
5218+ * so we'll have to unlock it below.
5219+ */
5220+
5221+ /* allocate dentry private data. We free it in ->d_release */
5222+ err = new_dentry_private_data(dentry, UNIONFS_DMUTEX_CHILD);
5223+ if (unlikely(err)) {
5224+ ret = ERR_PTR(err);
5225+ goto out;
5226+ }
5227+ ret = unionfs_lookup_full(dentry, nd, INTERPOSE_LOOKUP);
5228+
5229+ /* restore the dentry & vfsmnt in namei */
5230+ if (nd) {
5231+ nd->path.dentry = path_save.dentry;
5232+ nd->path.mnt = path_save.mnt;
5233+ }
5234+ if (!IS_ERR(ret)) {
5235+ if (ret)
5236+ dentry = ret;
5237+ /* lookup_full can return multiple positive dentries */
5238+ if (dentry->d_inode && !S_ISDIR(dentry->d_inode->i_mode)) {
5239+ BUG_ON(dbstart(dentry) < 0);
5240+ unionfs_postcopyup_release(dentry);
5241+ }
5242+ unionfs_copy_attr_times(dentry->d_inode);
5243+ /* parent times may have changed */
5244+ unionfs_copy_attr_times(dentry->d_parent->d_inode);
5245+ }
5246+
5247+ unionfs_check_inode(parent);
5248+ if (!IS_ERR(ret)) {
5249+ unionfs_check_dentry(dentry);
5250+ unionfs_check_nd(nd);
5251+ }
5252+ unionfs_unlock_dentry(dentry);
5253+
5254+out:
5255+ if (dentry != dentry->d_parent) {
5256+ unionfs_check_dentry(dentry->d_parent);
5257+ unionfs_unlock_dentry(dentry->d_parent);
5258+ }
5259+ unionfs_read_unlock(dentry->d_sb);
5260+
5261+ return ret;
5262+}
5263+
5264+static int unionfs_link(struct dentry *old_dentry, struct inode *dir,
5265+ struct dentry *new_dentry)
5266+{
5267+ int err = 0;
5268+ struct dentry *lower_old_dentry = NULL;
5269+ struct dentry *lower_new_dentry = NULL;
5270+ struct dentry *lower_dir_dentry = NULL;
5271+ char *name = NULL;
5272+
5273+ unionfs_read_lock(old_dentry->d_sb, UNIONFS_SMUTEX_CHILD);
5274+ unionfs_double_lock_dentry(new_dentry, old_dentry);
5275+
5276+ if (unlikely(!__unionfs_d_revalidate_chain(old_dentry, NULL, false))) {
5277+ err = -ESTALE;
5278+ goto out;
5279+ }
5280+ if (unlikely(new_dentry->d_inode &&
5281+ !__unionfs_d_revalidate_chain(new_dentry, NULL, false))) {
5282+ err = -ESTALE;
5283+ goto out;
5284+ }
5285+
5286+ lower_new_dentry = unionfs_lower_dentry(new_dentry);
5287+
5288+ /* check for a whiteout in new dentry branch, and delete it */
5289+ err = check_unlink_whiteout(new_dentry, lower_new_dentry,
5290+ dbstart(new_dentry));
5291+ if (err > 0) { /* whiteout found and removed successfully */
5292+ lower_dir_dentry = dget_parent(lower_new_dentry);
5293+ fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode);
5294+ dput(lower_dir_dentry);
5295+ dir->i_nlink = unionfs_get_nlinks(dir);
5296+ err = 0;
5297+ }
5298+ if (err)
5299+ goto out;
5300+
5301+ /* check if parent hierachy is needed, then link in same branch */
5302+ if (dbstart(old_dentry) != dbstart(new_dentry)) {
5303+ lower_new_dentry = create_parents(dir, new_dentry,
5304+ new_dentry->d_name.name,
5305+ dbstart(old_dentry));
5306+ err = PTR_ERR(lower_new_dentry);
5307+ if (IS_COPYUP_ERR(err))
5308+ goto docopyup;
5309+ if (!lower_new_dentry || IS_ERR(lower_new_dentry))
5310+ goto out;
5311+ }
5312+ lower_new_dentry = unionfs_lower_dentry(new_dentry);
5313+ lower_old_dentry = unionfs_lower_dentry(old_dentry);
5314+
5315+ BUG_ON(dbstart(old_dentry) != dbstart(new_dentry));
5316+ lower_dir_dentry = lock_parent(lower_new_dentry);
5317+ err = is_robranch(old_dentry);
5318+ if (!err) {
5319+ /* see Documentation/filesystems/unionfs/issues.txt */
5320+ lockdep_off();
5321+ err = vfs_link(lower_old_dentry, lower_dir_dentry->d_inode,
5322+ lower_new_dentry);
5323+ lockdep_on();
5324+ }
5325+ unlock_dir(lower_dir_dentry);
5326+
5327+docopyup:
5328+ if (IS_COPYUP_ERR(err)) {
5329+ int old_bstart = dbstart(old_dentry);
5330+ int bindex;
5331+
5332+ for (bindex = old_bstart - 1; bindex >= 0; bindex--) {
5333+ err = copyup_dentry(old_dentry->d_parent->d_inode,
5334+ old_dentry, old_bstart,
5335+ bindex, old_dentry->d_name.name,
5336+ old_dentry->d_name.len, NULL,
5337+ i_size_read(old_dentry->d_inode));
5338+ if (err)
5339+ continue;
5340+ lower_new_dentry =
5341+ create_parents(dir, new_dentry,
5342+ new_dentry->d_name.name,
5343+ bindex);
5344+ lower_old_dentry = unionfs_lower_dentry(old_dentry);
5345+ lower_dir_dentry = lock_parent(lower_new_dentry);
5346+ /* see Documentation/filesystems/unionfs/issues.txt */
5347+ lockdep_off();
5348+ /* do vfs_link */
5349+ err = vfs_link(lower_old_dentry,
5350+ lower_dir_dentry->d_inode,
5351+ lower_new_dentry);
5352+ lockdep_on();
5353+ unlock_dir(lower_dir_dentry);
5354+ goto check_link;
5355+ }
5356+ goto out;
5357+ }
5358+
5359+check_link:
5360+ if (err || !lower_new_dentry->d_inode)
5361+ goto out;
5362+
5363+ /* Its a hard link, so use the same inode */
5364+ new_dentry->d_inode = igrab(old_dentry->d_inode);
5365+ d_add(new_dentry, new_dentry->d_inode);
5366+ unionfs_copy_attr_all(dir, lower_new_dentry->d_parent->d_inode);
5367+ fsstack_copy_inode_size(dir, lower_new_dentry->d_parent->d_inode);
5368+
5369+ /* propagate number of hard-links */
5370+ old_dentry->d_inode->i_nlink = unionfs_get_nlinks(old_dentry->d_inode);
5371+ /* new dentry's ctime may have changed due to hard-link counts */
5372+ unionfs_copy_attr_times(new_dentry->d_inode);
5373+
5374+out:
5375+ if (!new_dentry->d_inode)
5376+ d_drop(new_dentry);
5377+
5378+ kfree(name);
5379+ if (!err)
5380+ unionfs_postcopyup_setmnt(new_dentry);
5381+
5382+ unionfs_check_inode(dir);
5383+ unionfs_check_dentry(new_dentry);
5384+ unionfs_check_dentry(old_dentry);
5385+
5386+ unionfs_unlock_dentry(new_dentry);
5387+ unionfs_unlock_dentry(old_dentry);
5388+ unionfs_read_unlock(old_dentry->d_sb);
5389+
5390+ return err;
5391+}
5392+
5393+static int unionfs_symlink(struct inode *parent, struct dentry *dentry,
5394+ const char *symname)
5395+{
5396+ int err = 0;
5397+ struct dentry *lower_dentry = NULL;
5398+ struct dentry *wh_dentry = NULL;
5399+ struct dentry *lower_parent_dentry = NULL;
5400+ char *name = NULL;
5401+ int valid = 0;
5402+ umode_t mode;
5403+
5404+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD);
5405+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
5406+ unionfs_lock_dentry(dentry->d_parent, UNIONFS_DMUTEX_PARENT);
5407+
5408+ valid = __unionfs_d_revalidate_chain(dentry->d_parent, NULL, false);
5409+ if (unlikely(!valid)) {
5410+ err = -ESTALE;
5411+ goto out;
5412+ }
5413+ if (unlikely(dentry->d_inode &&
5414+ !__unionfs_d_revalidate_one_locked(dentry, NULL, false))) {
5415+ err = -ESTALE;
5416+ goto out;
5417+ }
5418+
5419+ /*
5420+ * It's only a bug if this dentry was not negative and couldn't be
5421+ * revalidated (shouldn't happen).
5422+ */
5423+ BUG_ON(!valid && dentry->d_inode);
5424+
5425+ lower_dentry = find_writeable_branch(parent, dentry);
5426+ if (IS_ERR(lower_dentry)) {
5427+ err = PTR_ERR(lower_dentry);
5428+ goto out;
5429+ }
5430+
5431+ lower_parent_dentry = lock_parent(lower_dentry);
5432+ if (IS_ERR(lower_parent_dentry)) {
5433+ err = PTR_ERR(lower_parent_dentry);
5434+ goto out;
5435+ }
5436+
5437+ mode = S_IALLUGO;
5438+ err = vfs_symlink(lower_parent_dentry->d_inode, lower_dentry, symname);
5439+ if (!err) {
5440+ err = PTR_ERR(unionfs_interpose(dentry, parent->i_sb, 0));
5441+ if (!err) {
5442+ unionfs_copy_attr_times(parent);
5443+ fsstack_copy_inode_size(parent,
5444+ lower_parent_dentry->d_inode);
5445+ /* update no. of links on parent directory */
5446+ parent->i_nlink = unionfs_get_nlinks(parent);
5447+ }
5448+ }
5449+
5450+ unlock_dir(lower_parent_dentry);
5451+
5452+out:
5453+ dput(wh_dentry);
5454+ kfree(name);
5455+
5456+ if (!err) {
5457+ unionfs_postcopyup_setmnt(dentry);
5458+ unionfs_check_inode(parent);
5459+ unionfs_check_dentry(dentry);
5460+ }
5461+ unionfs_unlock_dentry(dentry->d_parent);
5462+ unionfs_unlock_dentry(dentry);
5463+ unionfs_read_unlock(dentry->d_sb);
5464+ return err;
5465+}
5466+
5467+static int unionfs_mkdir(struct inode *parent, struct dentry *dentry, int mode)
5468+{
5469+ int err = 0;
5470+ struct dentry *lower_dentry = NULL;
5471+ struct dentry *lower_parent_dentry = NULL;
5472+ int bindex = 0, bstart;
5473+ char *name = NULL;
5474+ int valid;
5475+
5476+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD);
5477+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
5478+ unionfs_lock_dentry(dentry->d_parent, UNIONFS_DMUTEX_PARENT);
5479+
5480+ valid = __unionfs_d_revalidate_chain(dentry->d_parent, NULL, false);
5481+ if (unlikely(!valid)) {
5482+ err = -ESTALE; /* same as what real_lookup does */
5483+ goto out;
5484+ }
5485+ if (unlikely(dentry->d_inode &&
5486+ !__unionfs_d_revalidate_one_locked(dentry, NULL, false))) {
5487+ err = -ESTALE;
5488+ goto out;
5489+ }
5490+
5491+ bstart = dbstart(dentry);
5492+
5493+ lower_dentry = unionfs_lower_dentry(dentry);
5494+
5495+ /* check for a whiteout in new dentry branch, and delete it */
5496+ err = check_unlink_whiteout(dentry, lower_dentry, bstart);
5497+ if (err > 0) /* whiteout found and removed successfully */
5498+ err = 0;
5499+ if (err) {
5500+ /* exit if the error returned was NOT -EROFS */
5501+ if (!IS_COPYUP_ERR(err))
5502+ goto out;
5503+ bstart--;
5504+ }
5505+
5506+ /* check if copyup's needed, and mkdir */
5507+ for (bindex = bstart; bindex >= 0; bindex--) {
5508+ int i;
5509+ int bend = dbend(dentry);
5510+
5511+ if (is_robranch_super(dentry->d_sb, bindex))
5512+ continue;
5513+
5514+ lower_dentry = unionfs_lower_dentry_idx(dentry, bindex);
5515+ if (!lower_dentry) {
5516+ lower_dentry = create_parents(parent, dentry,
5517+ dentry->d_name.name,
5518+ bindex);
5519+ if (!lower_dentry || IS_ERR(lower_dentry)) {
5520+ printk(KERN_ERR "unionfs: lower dentry "
5521+ " NULL for bindex = %d\n", bindex);
5522+ continue;
5523+ }
5524+ }
5525+
5526+ lower_parent_dentry = lock_parent(lower_dentry);
5527+
5528+ if (IS_ERR(lower_parent_dentry)) {
5529+ err = PTR_ERR(lower_parent_dentry);
5530+ goto out;
5531+ }
5532+
5533+ err = vfs_mkdir(lower_parent_dentry->d_inode, lower_dentry,
5534+ mode);
5535+
5536+ unlock_dir(lower_parent_dentry);
5537+
5538+ /* did the mkdir succeed? */
5539+ if (err)
5540+ break;
5541+
5542+ for (i = bindex + 1; i < bend; i++) {
5543+ if (unionfs_lower_dentry_idx(dentry, i)) {
5544+ dput(unionfs_lower_dentry_idx(dentry, i));
5545+ unionfs_set_lower_dentry_idx(dentry, i, NULL);
5546+ }
5547+ }
5548+ dbend(dentry) = bindex;
5549+
5550+ /*
5551+ * Only INTERPOSE_LOOKUP can return a value other than 0 on
5552+ * err.
5553+ */
5554+ err = PTR_ERR(unionfs_interpose(dentry, parent->i_sb, 0));
5555+ if (!err) {
5556+ unionfs_copy_attr_times(parent);
5557+ fsstack_copy_inode_size(parent,
5558+ lower_parent_dentry->d_inode);
5559+
5560+ /* update number of links on parent directory */
5561+ parent->i_nlink = unionfs_get_nlinks(parent);
5562+ }
5563+
5564+ err = make_dir_opaque(dentry, dbstart(dentry));
5565+ if (err) {
5566+ printk(KERN_ERR "unionfs: mkdir: error creating "
5567+ ".wh.__dir_opaque: %d\n", err);
5568+ goto out;
5569+ }
5570+
5571+ /* we are done! */
5572+ break;
5573+ }
5574+
5575+out:
5576+ if (!dentry->d_inode)
5577+ d_drop(dentry);
5578+
5579+ kfree(name);
5580+
5581+ if (!err) {
5582+ unionfs_copy_attr_times(dentry->d_inode);
5583+ unionfs_postcopyup_setmnt(dentry);
5584+ }
5585+ unionfs_check_inode(parent);
5586+ unionfs_check_dentry(dentry);
5587+ unionfs_unlock_dentry(dentry->d_parent);
5588+ unionfs_unlock_dentry(dentry);
5589+ unionfs_read_unlock(dentry->d_sb);
5590+
5591+ return err;
5592+}
5593+
5594+static int unionfs_mknod(struct inode *parent, struct dentry *dentry, int mode,
5595+ dev_t dev)
5596+{
5597+ int err = 0;
5598+ struct dentry *lower_dentry = NULL;
5599+ struct dentry *wh_dentry = NULL;
5600+ struct dentry *lower_parent_dentry = NULL;
5601+ char *name = NULL;
5602+ int valid = 0;
5603+
5604+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD);
5605+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
5606+ unionfs_lock_dentry(dentry->d_parent, UNIONFS_DMUTEX_PARENT);
5607+
5608+ valid = __unionfs_d_revalidate_chain(dentry->d_parent, NULL, false);
5609+ if (unlikely(!valid)) {
5610+ err = -ESTALE;
5611+ goto out;
5612+ }
5613+ if (unlikely(dentry->d_inode &&
5614+ !__unionfs_d_revalidate_one_locked(dentry, NULL, false))) {
5615+ err = -ESTALE;
5616+ goto out;
5617+ }
5618+
5619+ /*
5620+ * It's only a bug if this dentry was not negative and couldn't be
5621+ * revalidated (shouldn't happen).
5622+ */
5623+ BUG_ON(!valid && dentry->d_inode);
5624+
5625+ lower_dentry = find_writeable_branch(parent, dentry);
5626+ if (IS_ERR(lower_dentry)) {
5627+ err = PTR_ERR(lower_dentry);
5628+ goto out;
5629+ }
5630+
5631+ lower_parent_dentry = lock_parent(lower_dentry);
5632+ if (IS_ERR(lower_parent_dentry)) {
5633+ err = PTR_ERR(lower_parent_dentry);
5634+ goto out;
5635+ }
5636+
5637+ err = vfs_mknod(lower_parent_dentry->d_inode, lower_dentry, mode, dev);
5638+ if (!err) {
5639+ err = PTR_ERR(unionfs_interpose(dentry, parent->i_sb, 0));
5640+ if (!err) {
5641+ unionfs_copy_attr_times(parent);
5642+ fsstack_copy_inode_size(parent,
5643+ lower_parent_dentry->d_inode);
5644+ /* update no. of links on parent directory */
5645+ parent->i_nlink = unionfs_get_nlinks(parent);
5646+ }
5647+ }
5648+
5649+ unlock_dir(lower_parent_dentry);
5650+
5651+out:
5652+ dput(wh_dentry);
5653+ kfree(name);
5654+
5655+ if (!err) {
5656+ unionfs_postcopyup_setmnt(dentry);
5657+ unionfs_check_inode(parent);
5658+ unionfs_check_dentry(dentry);
5659+ }
5660+ unionfs_unlock_dentry(dentry->d_parent);
5661+ unionfs_unlock_dentry(dentry);
5662+ unionfs_read_unlock(dentry->d_sb);
5663+ return err;
5664+}
5665+
5666+static int unionfs_readlink(struct dentry *dentry, char __user *buf,
5667+ int bufsiz)
5668+{
5669+ int err;
5670+ struct dentry *lower_dentry;
5671+
5672+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD);
5673+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
5674+
5675+ if (unlikely(!__unionfs_d_revalidate_chain(dentry, NULL, false))) {
5676+ err = -ESTALE;
5677+ goto out;
5678+ }
5679+
5680+ lower_dentry = unionfs_lower_dentry(dentry);
5681+
5682+ if (!lower_dentry->d_inode->i_op ||
5683+ !lower_dentry->d_inode->i_op->readlink) {
5684+ err = -EINVAL;
5685+ goto out;
5686+ }
5687+
5688+ err = lower_dentry->d_inode->i_op->readlink(lower_dentry,
5689+ buf, bufsiz);
5690+ if (err > 0)
5691+ fsstack_copy_attr_atime(dentry->d_inode,
5692+ lower_dentry->d_inode);
5693+
5694+out:
5695+ unionfs_check_dentry(dentry);
5696+ unionfs_unlock_dentry(dentry);
5697+ unionfs_read_unlock(dentry->d_sb);
5698+
5699+ return err;
5700+}
5701+
5702+/*
5703+ * unionfs_follow_link takes a dentry, but it is simple. It only needs to
5704+ * allocate some memory and then call our ->readlink method. Our
5705+ * unionfs_readlink *does* lock our dentry and revalidate the dentry.
5706+ * Therefore, we do not have to lock our dentry here, to prevent a deadlock;
5707+ * nor do we need to revalidate it either. It is safe to not lock our
5708+ * dentry here, nor revalidate it, because unionfs_follow_link does not do
5709+ * anything (prior to calling ->readlink) which could become inconsistent
5710+ * due to branch management. We also don't need to lock our super because
5711+ * this function isn't affected by branch-management.
5712+ */
5713+static void *unionfs_follow_link(struct dentry *dentry, struct nameidata *nd)
5714+{
5715+ char *buf;
5716+ int len = PAGE_SIZE, err;
5717+ mm_segment_t old_fs;
5718+
5719+ /* This is freed by the put_link method assuming a successful call. */
5720+ buf = kmalloc(len, GFP_KERNEL);
5721+ if (unlikely(!buf)) {
5722+ err = -ENOMEM;
5723+ goto out;
5724+ }
5725+
5726+ /* read the symlink, and then we will follow it */
5727+ old_fs = get_fs();
5728+ set_fs(KERNEL_DS);
5729+ err = dentry->d_inode->i_op->readlink(dentry, (char __user *)buf, len);
5730+ set_fs(old_fs);
5731+ if (err < 0) {
5732+ kfree(buf);
5733+ buf = NULL;
5734+ goto out;
5735+ }
5736+ buf[err] = 0;
5737+ nd_set_link(nd, buf);
5738+ err = 0;
5739+
5740+out:
5741+ if (!err) {
5742+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
5743+ unionfs_check_dentry(dentry);
5744+ unionfs_unlock_dentry(dentry);
5745+ }
5746+ unionfs_check_nd(nd);
5747+ return ERR_PTR(err);
5748+}
5749+
5750+/* FIXME: We may not have to lock here */
5751+static void unionfs_put_link(struct dentry *dentry, struct nameidata *nd,
5752+ void *cookie)
5753+{
5754+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD);
5755+
5756+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
5757+ if (unlikely(!__unionfs_d_revalidate_chain(dentry, nd, false)))
5758+ printk(KERN_ERR
5759+ "unionfs: put_link failed to revalidate dentry\n");
5760+
5761+ unionfs_check_dentry(dentry);
5762+ unionfs_check_nd(nd);
5763+ kfree(nd_get_link(nd));
5764+ unionfs_unlock_dentry(dentry);
5765+ unionfs_read_unlock(dentry->d_sb);
5766+}
5767+
5768+/*
5769+ * Don't grab the superblock read-lock in unionfs_permission, which prevents
5770+ * a deadlock with the branch-management "add branch" code (which grabbed
5771+ * the write lock). It is safe to not grab the read lock here, because even
5772+ * with branch management taking place, there is no chance that
5773+ * unionfs_permission, or anything it calls, will use stale branch
5774+ * information.
5775+ */
5776+static int unionfs_permission(struct inode *inode, int mask)
5777+{
5778+ struct inode *lower_inode = NULL;
5779+ int err = 0;
5780+ int bindex, bstart, bend;
5781+ const int is_file = !S_ISDIR(inode->i_mode);
5782+ const int write_mask = (mask & MAY_WRITE) && !(mask & MAY_READ);
5783+
5784+ if (!UNIONFS_I(inode)->lower_inodes) {
5785+ if (is_file) /* dirs can be unlinked but chdir'ed to */
5786+ err = -ESTALE; /* force revalidate */
5787+ goto out;
5788+ }
5789+ bstart = ibstart(inode);
5790+ bend = ibend(inode);
5791+ if (unlikely(bstart < 0 || bend < 0)) {
5792+ /*
5793+ * With branch-management, we can get a stale inode here.
5794+ * If so, we return ESTALE back to link_path_walk, which
5795+ * would discard the dcache entry and re-lookup the
5796+ * dentry+inode. This should be equivalent to issuing
5797+ * __unionfs_d_revalidate_chain on nd.dentry here.
5798+ */
5799+ if (is_file) /* dirs can be unlinked but chdir'ed to */
5800+ err = -ESTALE; /* force revalidate */
5801+ goto out;
5802+ }
5803+
5804+ for (bindex = bstart; bindex <= bend; bindex++) {
5805+ lower_inode = unionfs_lower_inode_idx(inode, bindex);
5806+ if (!lower_inode)
5807+ continue;
5808+
5809+ /*
5810+ * check the condition for D-F-D underlying files/directories,
5811+ * we don't have to check for files, if we are checking for
5812+ * directories.
5813+ */
5814+ if (!is_file && !S_ISDIR(lower_inode->i_mode))
5815+ continue;
5816+
5817+ /*
5818+ * We check basic permissions, but we ignore any conditions
5819+ * such as readonly file systems or branches marked as
5820+ * readonly, because those conditions should lead to a
5821+ * copyup taking place later on.
5822+ */
5823+ err = inode_permission(lower_inode, mask);
5824+ if (err && bindex > 0) {
5825+ umode_t mode = lower_inode->i_mode;
5826+ if (is_robranch_super(inode->i_sb, bindex) &&
5827+ (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
5828+ err = 0;
5829+ if (IS_COPYUP_ERR(err))
5830+ err = 0;
5831+ }
5832+
5833+ /*
5834+ * The permissions are an intersection of the overall directory
5835+ * permissions, so we fail if one fails.
5836+ */
5837+ if (err)
5838+ goto out;
5839+
5840+ /* only the leftmost file matters. */
5841+ if (is_file || write_mask) {
5842+ if (is_file && write_mask) {
5843+ err = get_write_access(lower_inode);
5844+ if (!err)
5845+ put_write_access(lower_inode);
5846+ }
5847+ break;
5848+ }
5849+ }
5850+ /* sync times which may have changed (asynchronously) below */
5851+ unionfs_copy_attr_times(inode);
5852+
5853+out:
5854+ unionfs_check_inode(inode);
5855+ return err;
5856+}
5857+
5858+static int unionfs_setattr(struct dentry *dentry, struct iattr *ia)
5859+{
5860+ int err = 0;
5861+ struct dentry *lower_dentry;
5862+ struct inode *inode;
5863+ struct inode *lower_inode;
5864+ int bstart, bend, bindex;
5865+ loff_t size;
5866+
5867+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD);
5868+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
5869+
5870+ if (unlikely(!__unionfs_d_revalidate_chain(dentry, NULL, false))) {
5871+ err = -ESTALE;
5872+ goto out;
5873+ }
5874+
5875+ bstart = dbstart(dentry);
5876+ bend = dbend(dentry);
5877+ inode = dentry->d_inode;
5878+
5879+ /*
5880+ * mode change is for clearing setuid/setgid. Allow lower filesystem
5881+ * to reinterpret it in its own way.
5882+ */
5883+ if (ia->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID))
5884+ ia->ia_valid &= ~ATTR_MODE;
5885+
5886+ lower_dentry = unionfs_lower_dentry(dentry);
5887+ BUG_ON(!lower_dentry); /* should never happen after above revalidate */
5888+
5889+ /* copyup if the file is on a read only branch */
5890+ if (is_robranch_super(dentry->d_sb, bstart)
5891+ || IS_RDONLY(lower_dentry->d_inode)) {
5892+ /* check if we have a branch to copy up to */
5893+ if (bstart <= 0) {
5894+ err = -EACCES;
5895+ goto out;
5896+ }
5897+
5898+ if (ia->ia_valid & ATTR_SIZE)
5899+ size = ia->ia_size;
5900+ else
5901+ size = i_size_read(inode);
5902+ /* copyup to next available branch */
5903+ for (bindex = bstart - 1; bindex >= 0; bindex--) {
5904+ err = copyup_dentry(dentry->d_parent->d_inode,
5905+ dentry, bstart, bindex,
5906+ dentry->d_name.name,
5907+ dentry->d_name.len,
5908+ NULL, size);
5909+ if (!err)
5910+ break;
5911+ }
5912+ if (err)
5913+ goto out;
5914+ /* get updated lower_dentry after copyup */
5915+ lower_dentry = unionfs_lower_dentry(dentry);
5916+ }
5917+
5918+ lower_inode = unionfs_lower_inode(inode);
5919+
5920+ /*
5921+ * If shrinking, first truncate upper level to cancel writing dirty
5922+ * pages beyond the new eof; and also if its' maxbytes is more
5923+ * limiting (fail with -EFBIG before making any change to the lower
5924+ * level). There is no need to vmtruncate the upper level
5925+ * afterwards in the other cases: we fsstack_copy_inode_size from
5926+ * the lower level.
5927+ */
5928+ if (ia->ia_valid & ATTR_SIZE) {
5929+ size = i_size_read(inode);
5930+ if (ia->ia_size < size || (ia->ia_size > size &&
5931+ inode->i_sb->s_maxbytes < lower_inode->i_sb->s_maxbytes)) {
5932+ err = vmtruncate(inode, ia->ia_size);
5933+ if (err)
5934+ goto out;
5935+ }
5936+ }
5937+
5938+ /* notify the (possibly copied-up) lower inode */
5939+ mutex_lock(&lower_dentry->d_inode->i_mutex);
5940+ err = notify_change(lower_dentry, ia);
5941+ mutex_unlock(&lower_dentry->d_inode->i_mutex);
5942+ if (err)
5943+ goto out;
5944+
5945+ /* get attributes from the first lower inode */
5946+ unionfs_copy_attr_all(inode, lower_inode);
5947+ /*
5948+ * unionfs_copy_attr_all will copy the lower times to our inode if
5949+ * the lower ones are newer (useful for cache coherency). However,
5950+ * ->setattr is the only place in which we may have to copy the
5951+ * lower inode times absolutely, to support utimes(2).
5952+ */
5953+ if (ia->ia_valid & ATTR_MTIME_SET)
5954+ inode->i_mtime = lower_inode->i_mtime;
5955+ if (ia->ia_valid & ATTR_CTIME)
5956+ inode->i_ctime = lower_inode->i_ctime;
5957+ if (ia->ia_valid & ATTR_ATIME_SET)
5958+ inode->i_atime = lower_inode->i_atime;
5959+ fsstack_copy_inode_size(inode, lower_inode);
5960+
5961+out:
5962+ if (!err)
5963+ unionfs_check_dentry(dentry);
5964+ unionfs_unlock_dentry(dentry);
5965+ unionfs_read_unlock(dentry->d_sb);
5966+
5967+ return err;
5968+}
5969+
5970+struct inode_operations unionfs_symlink_iops = {
5971+ .readlink = unionfs_readlink,
5972+ .permission = unionfs_permission,
5973+ .follow_link = unionfs_follow_link,
5974+ .setattr = unionfs_setattr,
5975+ .put_link = unionfs_put_link,
5976+};
5977+
5978+struct inode_operations unionfs_dir_iops = {
5979+ .create = unionfs_create,
5980+ .lookup = unionfs_lookup,
5981+ .link = unionfs_link,
5982+ .unlink = unionfs_unlink,
5983+ .symlink = unionfs_symlink,
5984+ .mkdir = unionfs_mkdir,
5985+ .rmdir = unionfs_rmdir,
5986+ .mknod = unionfs_mknod,
5987+ .rename = unionfs_rename,
5988+ .permission = unionfs_permission,
5989+ .setattr = unionfs_setattr,
5990+#ifdef CONFIG_UNION_FS_XATTR
5991+ .setxattr = unionfs_setxattr,
5992+ .getxattr = unionfs_getxattr,
5993+ .removexattr = unionfs_removexattr,
5994+ .listxattr = unionfs_listxattr,
5995+#endif /* CONFIG_UNION_FS_XATTR */
5996+};
5997+
5998+struct inode_operations unionfs_main_iops = {
5999+ .permission = unionfs_permission,
6000+ .setattr = unionfs_setattr,
6001+#ifdef CONFIG_UNION_FS_XATTR
6002+ .setxattr = unionfs_setxattr,
6003+ .getxattr = unionfs_getxattr,
6004+ .removexattr = unionfs_removexattr,
6005+ .listxattr = unionfs_listxattr,
6006+#endif /* CONFIG_UNION_FS_XATTR */
6007+};
6008diff --git a/fs/unionfs/lookup.c b/fs/unionfs/lookup.c
6009new file mode 100644
6010index 0000000..0a9602a
6011--- /dev/null
6012+++ b/fs/unionfs/lookup.c
6013@@ -0,0 +1,570 @@
6014+/*
6015+ * Copyright (c) 2003-2008 Erez Zadok
6016+ * Copyright (c) 2003-2006 Charles P. Wright
6017+ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
6018+ * Copyright (c) 2005-2006 Junjiro Okajima
6019+ * Copyright (c) 2005 Arun M. Krishnakumar
6020+ * Copyright (c) 2004-2006 David P. Quigley
6021+ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
6022+ * Copyright (c) 2003 Puja Gupta
6023+ * Copyright (c) 2003 Harikesavan Krishnan
6024+ * Copyright (c) 2003-2008 Stony Brook University
6025+ * Copyright (c) 2003-2008 The Research Foundation of SUNY
6026+ *
6027+ * This program is free software; you can redistribute it and/or modify
6028+ * it under the terms of the GNU General Public License version 2 as
6029+ * published by the Free Software Foundation.
6030+ */
6031+
6032+#include "union.h"
6033+
6034+/*
6035+ * Lookup one path component @name relative to a <base,mnt> path pair.
6036+ * Behaves nearly the same as lookup_one_len (i.e., return negative dentry
6037+ * on ENOENT), but uses the @mnt passed, so it can cross bind mounts and
6038+ * other lower mounts properly. If @new_mnt is non-null, will fill in the
6039+ * new mnt there. Caller is responsible to dput/mntput/path_put returned
6040+ * @dentry and @new_mnt.
6041+ */
6042+struct dentry *__lookup_one(struct dentry *base, struct vfsmount *mnt,
6043+ const char *name, struct vfsmount **new_mnt)
6044+{
6045+ struct dentry *dentry = NULL;
6046+ struct nameidata lower_nd;
6047+ int err;
6048+
6049+ /* we use flags=0 to get basic lookup */
6050+ err = vfs_path_lookup(base, mnt, name, 0, &lower_nd);
6051+
6052+ switch (err) {
6053+ case 0: /* no error */
6054+ dentry = lower_nd.path.dentry;
6055+ if (new_mnt)
6056+ *new_mnt = lower_nd.path.mnt; /* rc already inc'ed */
6057+ break;
6058+ case -ENOENT:
6059+ /*
6060+ * We don't consider ENOENT an error, and we want to return
6061+ * a negative dentry (ala lookup_one_len). As we know
6062+ * there was no inode for this name before (-ENOENT), then
6063+ * it's safe to call lookup_one_len (which doesn't take a
6064+ * vfsmount).
6065+ */
6066+ dentry = lookup_one_len(name, base, strlen(name));
6067+ if (new_mnt)
6068+ *new_mnt = mntget(lower_nd.path.mnt);
6069+ break;
6070+ default: /* all other real errors */
6071+ dentry = ERR_PTR(err);
6072+ break;
6073+ }
6074+
6075+ return dentry;
6076+}
6077+
6078+/*
6079+ * This is a utility function that fills in a unionfs dentry.
6080+ * Caller must lock this dentry with unionfs_lock_dentry.
6081+ *
6082+ * Returns: 0 (ok), or -ERRNO if an error occurred.
6083+ * XXX: get rid of _partial_lookup and make callers call _lookup_full directly
6084+ */
6085+int unionfs_partial_lookup(struct dentry *dentry)
6086+{
6087+ struct dentry *tmp;
6088+ struct nameidata nd = { .flags = 0 };
6089+ int err = -ENOSYS;
6090+
6091+ tmp = unionfs_lookup_full(dentry, &nd, INTERPOSE_PARTIAL);
6092+
6093+ if (!tmp) {
6094+ err = 0;
6095+ goto out;
6096+ }
6097+ if (IS_ERR(tmp)) {
6098+ err = PTR_ERR(tmp);
6099+ goto out;
6100+ }
6101+ /* XXX: need to change the interface */
6102+ BUG_ON(tmp != dentry);
6103+out:
6104+ return err;
6105+}
6106+
6107+/* The dentry cache is just so we have properly sized dentries. */
6108+static struct kmem_cache *unionfs_dentry_cachep;
6109+int unionfs_init_dentry_cache(void)
6110+{
6111+ unionfs_dentry_cachep =
6112+ kmem_cache_create("unionfs_dentry",
6113+ sizeof(struct unionfs_dentry_info),
6114+ 0, SLAB_RECLAIM_ACCOUNT, NULL);
6115+
6116+ return (unionfs_dentry_cachep ? 0 : -ENOMEM);
6117+}
6118+
6119+void unionfs_destroy_dentry_cache(void)
6120+{
6121+ if (unionfs_dentry_cachep)
6122+ kmem_cache_destroy(unionfs_dentry_cachep);
6123+}
6124+
6125+void free_dentry_private_data(struct dentry *dentry)
6126+{
6127+ if (!dentry || !dentry->d_fsdata)
6128+ return;
6129+ kfree(UNIONFS_D(dentry)->lower_paths);
6130+ UNIONFS_D(dentry)->lower_paths = NULL;
6131+ kmem_cache_free(unionfs_dentry_cachep, dentry->d_fsdata);
6132+ dentry->d_fsdata = NULL;
6133+}
6134+
6135+static inline int __realloc_dentry_private_data(struct dentry *dentry)
6136+{
6137+ struct unionfs_dentry_info *info = UNIONFS_D(dentry);
6138+ void *p;
6139+ int size;
6140+
6141+ BUG_ON(!info);
6142+
6143+ size = sizeof(struct path) * sbmax(dentry->d_sb);
6144+ p = krealloc(info->lower_paths, size, GFP_ATOMIC);
6145+ if (unlikely(!p))
6146+ return -ENOMEM;
6147+
6148+ info->lower_paths = p;
6149+
6150+ info->bstart = -1;
6151+ info->bend = -1;
6152+ info->bopaque = -1;
6153+ info->bcount = sbmax(dentry->d_sb);
6154+ atomic_set(&info->generation,
6155+ atomic_read(&UNIONFS_SB(dentry->d_sb)->generation));
6156+
6157+ memset(info->lower_paths, 0, size);
6158+
6159+ return 0;
6160+}
6161+
6162+/* UNIONFS_D(dentry)->lock must be locked */
6163+int realloc_dentry_private_data(struct dentry *dentry)
6164+{
6165+ if (!__realloc_dentry_private_data(dentry))
6166+ return 0;
6167+
6168+ kfree(UNIONFS_D(dentry)->lower_paths);
6169+ free_dentry_private_data(dentry);
6170+ return -ENOMEM;
6171+}
6172+
6173+/* allocate new dentry private data */
6174+int new_dentry_private_data(struct dentry *dentry, int subclass)
6175+{
6176+ struct unionfs_dentry_info *info = UNIONFS_D(dentry);
6177+
6178+ BUG_ON(info);
6179+
6180+ info = kmem_cache_alloc(unionfs_dentry_cachep, GFP_ATOMIC);
6181+ if (unlikely(!info))
6182+ return -ENOMEM;
6183+
6184+ mutex_init(&info->lock);
6185+ mutex_lock_nested(&info->lock, subclass);
6186+
6187+ info->lower_paths = NULL;
6188+
6189+ dentry->d_fsdata = info;
6190+
6191+ if (!__realloc_dentry_private_data(dentry))
6192+ return 0;
6193+
6194+ mutex_unlock(&info->lock);
6195+ free_dentry_private_data(dentry);
6196+ return -ENOMEM;
6197+}
6198+
6199+/*
6200+ * scan through the lower dentry objects, and set bstart to reflect the
6201+ * starting branch
6202+ */
6203+void update_bstart(struct dentry *dentry)
6204+{
6205+ int bindex;
6206+ int bstart = dbstart(dentry);
6207+ int bend = dbend(dentry);
6208+ struct dentry *lower_dentry;
6209+
6210+ for (bindex = bstart; bindex <= bend; bindex++) {
6211+ lower_dentry = unionfs_lower_dentry_idx(dentry, bindex);
6212+ if (!lower_dentry)
6213+ continue;
6214+ if (lower_dentry->d_inode) {
6215+ dbstart(dentry) = bindex;
6216+ break;
6217+ }
6218+ dput(lower_dentry);
6219+ unionfs_set_lower_dentry_idx(dentry, bindex, NULL);
6220+ }
6221+}
6222+
6223+
6224+/*
6225+ * Initialize a nameidata structure (the intent part) we can pass to a lower
6226+ * file system. Returns 0 on success or -error (only -ENOMEM possible).
6227+ * Inside that nd structure, this function may also return an allocated
6228+ * struct file (for open intents). The caller, when done with this nd, must
6229+ * kfree the intent file (using release_lower_nd).
6230+ *
6231+ * XXX: this code, and the callers of this code, should be redone using
6232+ * vfs_path_lookup() when (1) the nameidata structure is refactored into a
6233+ * separate intent-structure, and (2) open_namei() is broken into a VFS-only
6234+ * function and a method that other file systems can call.
6235+ */
6236+int init_lower_nd(struct nameidata *nd, unsigned int flags)
6237+{
6238+ int err = 0;
6239+#ifdef ALLOC_LOWER_ND_FILE
6240+ /*
6241+ * XXX: one day we may need to have the lower return an open file
6242+ * for us. It is not needed in 2.6.23-rc1 for nfs2/nfs3, but may
6243+ * very well be needed for nfs4.
6244+ */
6245+ struct file *file;
6246+#endif /* ALLOC_LOWER_ND_FILE */
6247+
6248+ memset(nd, 0, sizeof(struct nameidata));
6249+ if (!flags)
6250+ return err;
6251+
6252+ switch (flags) {
6253+ case LOOKUP_CREATE:
6254+ nd->intent.open.flags |= O_CREAT;
6255+ /* fall through: shared code for create/open cases */
6256+ case LOOKUP_OPEN:
6257+ nd->flags = flags;
6258+ nd->intent.open.flags |= (FMODE_READ | FMODE_WRITE);
6259+#ifdef ALLOC_LOWER_ND_FILE
6260+ file = kzalloc(sizeof(struct file), GFP_KERNEL);
6261+ if (unlikely(!file)) {
6262+ err = -ENOMEM;
6263+ break; /* exit switch statement and thus return */
6264+ }
6265+ nd->intent.open.file = file;
6266+#endif /* ALLOC_LOWER_ND_FILE */
6267+ break;
6268+ default:
6269+ /*
6270+ * We should never get here, for now.
6271+ * We can add new cases here later on.
6272+ */
6273+ pr_debug("unionfs: unknown nameidata flag 0x%x\n", flags);
6274+ BUG();
6275+ break;
6276+ }
6277+
6278+ return err;
6279+}
6280+
6281+void release_lower_nd(struct nameidata *nd, int err)
6282+{
6283+ if (!nd->intent.open.file)
6284+ return;
6285+ else if (!err)
6286+ release_open_intent(nd);
6287+#ifdef ALLOC_LOWER_ND_FILE
6288+ kfree(nd->intent.open.file);
6289+#endif /* ALLOC_LOWER_ND_FILE */
6290+}
6291+
6292+/*
6293+ * Main (and complex) driver function for Unionfs's lookup
6294+ *
6295+ * Returns: NULL (ok), ERR_PTR if an error occurred, or a non-null non-error
6296+ * PTR if d_splice returned a different dentry.
6297+ *
6298+ * If lookupmode is INTERPOSE_PARTIAL/REVAL/REVAL_NEG, the passed dentry's
6299+ * inode info must be locked. If lookupmode is INTERPOSE_LOOKUP (i.e., a
6300+ * newly looked-up dentry), then unionfs_lookup_backend will return a locked
6301+ * dentry's info, which the caller must unlock.
6302+ */
6303+struct dentry *unionfs_lookup_full(struct dentry *dentry,
6304+ struct nameidata *nd_unused, int lookupmode)
6305+{
6306+ int err = 0;
6307+ struct dentry *lower_dentry = NULL;
6308+ struct vfsmount *lower_mnt;
6309+ struct vfsmount *lower_dir_mnt;
6310+ struct dentry *wh_lower_dentry = NULL;
6311+ struct dentry *lower_dir_dentry = NULL;
6312+ struct dentry *parent_dentry = NULL;
6313+ struct dentry *d_interposed = NULL;
6314+ int bindex, bstart, bend, bopaque;
6315+ int opaque, num_positive = 0;
6316+ const char *name;
6317+ int namelen;
6318+ int pos_start, pos_end;
6319+
6320+ /*
6321+ * We should already have a lock on this dentry in the case of a
6322+ * partial lookup, or a revalidation. Otherwise it is returned from
6323+ * new_dentry_private_data already locked.
6324+ */
6325+ verify_locked(dentry);
6326+
6327+ /* must initialize dentry operations */
6328+ dentry->d_op = &unionfs_dops;
6329+
6330+ /* We never partial lookup the root directory. */
6331+ if (IS_ROOT(dentry))
6332+ goto out;
6333+ parent_dentry = dget_parent(dentry);
6334+
6335+ name = dentry->d_name.name;
6336+ namelen = dentry->d_name.len;
6337+
6338+ /* No dentries should get created for possible whiteout names. */
6339+ if (!is_validname(name)) {
6340+ err = -EPERM;
6341+ goto out_free;
6342+ }
6343+
6344+ /* Now start the actual lookup procedure. */
6345+ bstart = dbstart(parent_dentry);
6346+ bend = dbend(parent_dentry);
6347+ bopaque = dbopaque(parent_dentry);
6348+ BUG_ON(bstart < 0);
6349+
6350+ /* adjust bend to bopaque if needed */
6351+ if ((bopaque >= 0) && (bopaque < bend))
6352+ bend = bopaque;
6353+
6354+ /* lookup all possible dentries */
6355+ for (bindex = bstart; bindex <= bend; bindex++) {
6356+
6357+ lower_dentry = unionfs_lower_dentry_idx(dentry, bindex);
6358+ lower_mnt = unionfs_lower_mnt_idx(dentry, bindex);
6359+
6360+ /* skip if we already have a positive lower dentry */
6361+ if (lower_dentry) {
6362+ if (dbstart(dentry) < 0)
6363+ dbstart(dentry) = bindex;
6364+ if (bindex > dbend(dentry))
6365+ dbend(dentry) = bindex;
6366+ if (lower_dentry->d_inode)
6367+ num_positive++;
6368+ continue;
6369+ }
6370+
6371+ lower_dir_dentry =
6372+ unionfs_lower_dentry_idx(parent_dentry, bindex);
6373+ /* if the lower dentry's parent does not exist, skip this */
6374+ if (!lower_dir_dentry || !lower_dir_dentry->d_inode)
6375+ continue;
6376+
6377+ /* also skip it if the parent isn't a directory. */
6378+ if (!S_ISDIR(lower_dir_dentry->d_inode->i_mode))
6379+ continue; /* XXX: should be BUG_ON */
6380+
6381+ /* check for whiteouts: stop lookup if found */
6382+ wh_lower_dentry = lookup_whiteout(name, lower_dir_dentry);
6383+ if (IS_ERR(wh_lower_dentry)) {
6384+ err = PTR_ERR(wh_lower_dentry);
6385+ goto out_free;
6386+ }
6387+ if (wh_lower_dentry->d_inode) {
6388+ dbend(dentry) = dbopaque(dentry) = bindex;
6389+ if (dbstart(dentry) < 0)
6390+ dbstart(dentry) = bindex;
6391+ dput(wh_lower_dentry);
6392+ break;
6393+ }
6394+ dput(wh_lower_dentry);
6395+
6396+ /* Now do regular lookup; lookup @name */
6397+ lower_dir_mnt = unionfs_lower_mnt_idx(parent_dentry, bindex);
6398+ lower_mnt = NULL; /* XXX: needed? */
6399+
6400+ lower_dentry = __lookup_one(lower_dir_dentry, lower_dir_mnt,
6401+ name, &lower_mnt);
6402+
6403+ if (IS_ERR(lower_dentry)) {
6404+ err = PTR_ERR(lower_dentry);
6405+ goto out_free;
6406+ }
6407+ unionfs_set_lower_dentry_idx(dentry, bindex, lower_dentry);
6408+ BUG_ON(!lower_mnt);
6409+ unionfs_set_lower_mnt_idx(dentry, bindex, lower_mnt);
6410+
6411+ /* adjust dbstart/end */
6412+ if (dbstart(dentry) < 0)
6413+ dbstart(dentry) = bindex;
6414+ if (bindex > dbend(dentry))
6415+ dbend(dentry) = bindex;
6416+ /*
6417+ * We always store the lower dentries above, and update
6418+ * dbstart/dbend, even if the whole unionfs dentry is
6419+ * negative (i.e., no lower inodes).
6420+ */
6421+ if (!lower_dentry->d_inode)
6422+ continue;
6423+ num_positive++;
6424+
6425+ /*
6426+ * check if we just found an opaque directory, if so, stop
6427+ * lookups here.
6428+ */
6429+ if (!S_ISDIR(lower_dentry->d_inode->i_mode))
6430+ continue;
6431+ opaque = is_opaque_dir(dentry, bindex);
6432+ if (opaque < 0) {
6433+ err = opaque;
6434+ goto out_free;
6435+ } else if (opaque) {
6436+ dbend(dentry) = dbopaque(dentry) = bindex;
6437+ break;
6438+ }
6439+ dbend(dentry) = bindex;
6440+
6441+ /* update parent directory's atime with the bindex */
6442+ fsstack_copy_attr_atime(parent_dentry->d_inode,
6443+ lower_dir_dentry->d_inode);
6444+ }
6445+
6446+ /* sanity checks, then decide if to process a negative dentry */
6447+ BUG_ON(dbstart(dentry) < 0 && dbend(dentry) >= 0);
6448+ BUG_ON(dbstart(dentry) >= 0 && dbend(dentry) < 0);
6449+
6450+ if (num_positive > 0)
6451+ goto out_positive;
6452+
6453+ /*** handle NEGATIVE dentries ***/
6454+
6455+ /*
6456+ * If negative, keep only first lower negative dentry, to save on
6457+ * memory.
6458+ */
6459+ if (dbstart(dentry) < dbend(dentry)) {
6460+ path_put_lowers(dentry, dbstart(dentry) + 1,
6461+ dbend(dentry), false);
6462+ dbend(dentry) = dbstart(dentry);
6463+ }
6464+ if (lookupmode == INTERPOSE_PARTIAL)
6465+ goto out;
6466+ if (lookupmode == INTERPOSE_LOOKUP) {
6467+ /*
6468+ * If all we found was a whiteout in the first available
6469+ * branch, then create a negative dentry for a possibly new
6470+ * file to be created.
6471+ */
6472+ if (dbopaque(dentry) < 0)
6473+ goto out;
6474+ /* XXX: need to get mnt here */
6475+ bindex = dbstart(dentry);
6476+ if (unionfs_lower_dentry_idx(dentry, bindex))
6477+ goto out;
6478+ lower_dir_dentry =
6479+ unionfs_lower_dentry_idx(parent_dentry, bindex);
6480+ if (!lower_dir_dentry || !lower_dir_dentry->d_inode)
6481+ goto out;
6482+ if (!S_ISDIR(lower_dir_dentry->d_inode->i_mode))
6483+ goto out; /* XXX: should be BUG_ON */
6484+ /* XXX: do we need to cross bind mounts here? */
6485+ lower_dentry = lookup_one_len(name, lower_dir_dentry, namelen);
6486+ if (IS_ERR(lower_dentry)) {
6487+ err = PTR_ERR(lower_dentry);
6488+ goto out;
6489+ }
6490+ /* XXX: need to mntget/mntput as needed too! */
6491+ unionfs_set_lower_dentry_idx(dentry, bindex, lower_dentry);
6492+ /* XXX: wrong mnt for crossing bind mounts! */
6493+ lower_mnt = unionfs_mntget(dentry->d_sb->s_root, bindex);
6494+ unionfs_set_lower_mnt_idx(dentry, bindex, lower_mnt);
6495+
6496+ goto out;
6497+ }
6498+
6499+ /* if we're revalidating a positive dentry, don't make it negative */
6500+ if (lookupmode != INTERPOSE_REVAL)
6501+ d_add(dentry, NULL);
6502+
6503+ goto out;
6504+
6505+out_positive:
6506+ /*** handle POSITIVE dentries ***/
6507+
6508+ /*
6509+ * This unionfs dentry is positive (at least one lower inode
6510+ * exists), so scan entire dentry from beginning to end, and remove
6511+ * any negative lower dentries, if any. Then, update dbstart/dbend
6512+ * to reflect the start/end of positive dentries.
6513+ */
6514+ pos_start = pos_end = -1;
6515+ for (bindex = bstart; bindex <= bend; bindex++) {
6516+ lower_dentry = unionfs_lower_dentry_idx(dentry,
6517+ bindex);
6518+ if (lower_dentry && lower_dentry->d_inode) {
6519+ if (pos_start < 0)
6520+ pos_start = bindex;
6521+ if (bindex > pos_end)
6522+ pos_end = bindex;
6523+ continue;
6524+ }
6525+ path_put_lowers(dentry, bindex, bindex, false);
6526+ }
6527+ if (pos_start >= 0)
6528+ dbstart(dentry) = pos_start;
6529+ if (pos_end >= 0)
6530+ dbend(dentry) = pos_end;
6531+
6532+ /* Partial lookups need to re-interpose, or throw away older negs. */
6533+ if (lookupmode == INTERPOSE_PARTIAL) {
6534+ if (dentry->d_inode) {
6535+ unionfs_reinterpose(dentry);
6536+ goto out;
6537+ }
6538+
6539+ /*
6540+ * This dentry was positive, so it is as if we had a
6541+ * negative revalidation.
6542+ */
6543+ lookupmode = INTERPOSE_REVAL_NEG;
6544+ update_bstart(dentry);
6545+ }
6546+
6547+ /*
6548+ * Interpose can return a dentry if d_splice returned a different
6549+ * dentry.
6550+ */
6551+ d_interposed = unionfs_interpose(dentry, dentry->d_sb, lookupmode);
6552+ if (IS_ERR(d_interposed))
6553+ err = PTR_ERR(d_interposed);
6554+ else if (d_interposed)
6555+ dentry = d_interposed;
6556+
6557+ if (!err)
6558+ goto out;
6559+ d_drop(dentry);
6560+
6561+out_free:
6562+ /* should dput/mntput all the underlying dentries on error condition */
6563+ if (dbstart(dentry) >= 0)
6564+ path_put_lowers_all(dentry, false);
6565+ /* free lower_paths unconditionally */
6566+ kfree(UNIONFS_D(dentry)->lower_paths);
6567+ UNIONFS_D(dentry)->lower_paths = NULL;
6568+
6569+out:
6570+ if (dentry && UNIONFS_D(dentry)) {
6571+ BUG_ON(dbstart(dentry) < 0 && dbend(dentry) >= 0);
6572+ BUG_ON(dbstart(dentry) >= 0 && dbend(dentry) < 0);
6573+ }
6574+ if (d_interposed && UNIONFS_D(d_interposed)) {
6575+ BUG_ON(dbstart(d_interposed) < 0 && dbend(d_interposed) >= 0);
6576+ BUG_ON(dbstart(d_interposed) >= 0 && dbend(d_interposed) < 0);
6577+ }
6578+
6579+ dput(parent_dentry);
6580+ if (!err && d_interposed)
6581+ return d_interposed;
6582+ return ERR_PTR(err);
6583+}
6584diff --git a/fs/unionfs/main.c b/fs/unionfs/main.c
6585new file mode 100644
6586index 0000000..fea670b
6587--- /dev/null
6588+++ b/fs/unionfs/main.c
6589@@ -0,0 +1,777 @@
6590+/*
6591+ * Copyright (c) 2003-2008 Erez Zadok
6592+ * Copyright (c) 2003-2006 Charles P. Wright
6593+ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
6594+ * Copyright (c) 2005-2006 Junjiro Okajima
6595+ * Copyright (c) 2005 Arun M. Krishnakumar
6596+ * Copyright (c) 2004-2006 David P. Quigley
6597+ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
6598+ * Copyright (c) 2003 Puja Gupta
6599+ * Copyright (c) 2003 Harikesavan Krishnan
6600+ * Copyright (c) 2003-2008 Stony Brook University
6601+ * Copyright (c) 2003-2008 The Research Foundation of SUNY
6602+ *
6603+ * This program is free software; you can redistribute it and/or modify
6604+ * it under the terms of the GNU General Public License version 2 as
6605+ * published by the Free Software Foundation.
6606+ */
6607+
6608+#include "union.h"
6609+#include <linux/module.h>
6610+#include <linux/moduleparam.h>
6611+
6612+static void unionfs_fill_inode(struct dentry *dentry,
6613+ struct inode *inode)
6614+{
6615+ struct inode *lower_inode;
6616+ struct dentry *lower_dentry;
6617+ int bindex, bstart, bend;
6618+
6619+ bstart = dbstart(dentry);
6620+ bend = dbend(dentry);
6621+
6622+ for (bindex = bstart; bindex <= bend; bindex++) {
6623+ lower_dentry = unionfs_lower_dentry_idx(dentry, bindex);
6624+ if (!lower_dentry) {
6625+ unionfs_set_lower_inode_idx(inode, bindex, NULL);
6626+ continue;
6627+ }
6628+
6629+ /* Initialize the lower inode to the new lower inode. */
6630+ if (!lower_dentry->d_inode)
6631+ continue;
6632+
6633+ unionfs_set_lower_inode_idx(inode, bindex,
6634+ igrab(lower_dentry->d_inode));
6635+ }
6636+
6637+ ibstart(inode) = dbstart(dentry);
6638+ ibend(inode) = dbend(dentry);
6639+
6640+ /* Use attributes from the first branch. */
6641+ lower_inode = unionfs_lower_inode(inode);
6642+
6643+ /* Use different set of inode ops for symlinks & directories */
6644+ if (S_ISLNK(lower_inode->i_mode))
6645+ inode->i_op = &unionfs_symlink_iops;
6646+ else if (S_ISDIR(lower_inode->i_mode))
6647+ inode->i_op = &unionfs_dir_iops;
6648+
6649+ /* Use different set of file ops for directories */
6650+ if (S_ISDIR(lower_inode->i_mode))
6651+ inode->i_fop = &unionfs_dir_fops;
6652+
6653+ /* properly initialize special inodes */
6654+ if (S_ISBLK(lower_inode->i_mode) || S_ISCHR(lower_inode->i_mode) ||
6655+ S_ISFIFO(lower_inode->i_mode) || S_ISSOCK(lower_inode->i_mode))
6656+ init_special_inode(inode, lower_inode->i_mode,
6657+ lower_inode->i_rdev);
6658+
6659+ /* all well, copy inode attributes */
6660+ unionfs_copy_attr_all(inode, lower_inode);
6661+ fsstack_copy_inode_size(inode, lower_inode);
6662+}
6663+
6664+/*
6665+ * Connect a unionfs inode dentry/inode with several lower ones. This is
6666+ * the classic stackable file system "vnode interposition" action.
6667+ *
6668+ * @sb: unionfs's super_block
6669+ */
6670+struct dentry *unionfs_interpose(struct dentry *dentry, struct super_block *sb,
6671+ int flag)
6672+{
6673+ int err = 0;
6674+ struct inode *inode;
6675+ int need_fill_inode = 1;
6676+ struct dentry *spliced = NULL;
6677+
6678+ verify_locked(dentry);
6679+
6680+ /*
6681+ * We allocate our new inode below by calling unionfs_iget,
6682+ * which will initialize some of the new inode's fields
6683+ */
6684+
6685+ /*
6686+ * On revalidate we've already got our own inode and just need
6687+ * to fix it up.
6688+ */
6689+ if (flag == INTERPOSE_REVAL) {
6690+ inode = dentry->d_inode;
6691+ UNIONFS_I(inode)->bstart = -1;
6692+ UNIONFS_I(inode)->bend = -1;
6693+ atomic_set(&UNIONFS_I(inode)->generation,
6694+ atomic_read(&UNIONFS_SB(sb)->generation));
6695+
6696+ UNIONFS_I(inode)->lower_inodes =
6697+ kcalloc(sbmax(sb), sizeof(struct inode *), GFP_KERNEL);
6698+ if (unlikely(!UNIONFS_I(inode)->lower_inodes)) {
6699+ err = -ENOMEM;
6700+ goto out;
6701+ }
6702+ } else {
6703+ /* get unique inode number for unionfs */
6704+ inode = unionfs_iget(sb, iunique(sb, UNIONFS_ROOT_INO));
6705+ if (IS_ERR(inode)) {
6706+ err = PTR_ERR(inode);
6707+ goto out;
6708+ }
6709+ if (atomic_read(&inode->i_count) > 1)
6710+ goto skip;
6711+ }
6712+
6713+ need_fill_inode = 0;
6714+ unionfs_fill_inode(dentry, inode);
6715+
6716+skip:
6717+ /* only (our) lookup wants to do a d_add */
6718+ switch (flag) {
6719+ case INTERPOSE_DEFAULT:
6720+ /* for operations which create new inodes */
6721+ d_add(dentry, inode);
6722+ break;
6723+ case INTERPOSE_REVAL_NEG:
6724+ d_instantiate(dentry, inode);
6725+ break;
6726+ case INTERPOSE_LOOKUP:
6727+ spliced = d_splice_alias(inode, dentry);
6728+ if (spliced && spliced != dentry) {
6729+ /*
6730+ * d_splice can return a dentry if it was
6731+ * disconnected and had to be moved. We must ensure
6732+ * that the private data of the new dentry is
6733+ * correct and that the inode info was filled
6734+ * properly. Finally we must return this new
6735+ * dentry.
6736+ */
6737+ spliced->d_op = &unionfs_dops;
6738+ spliced->d_fsdata = dentry->d_fsdata;
6739+ dentry->d_fsdata = NULL;
6740+ dentry = spliced;
6741+ if (need_fill_inode) {
6742+ need_fill_inode = 0;
6743+ unionfs_fill_inode(dentry, inode);
6744+ }
6745+ goto out_spliced;
6746+ } else if (!spliced) {
6747+ if (need_fill_inode) {
6748+ need_fill_inode = 0;
6749+ unionfs_fill_inode(dentry, inode);
6750+ goto out_spliced;
6751+ }
6752+ }
6753+ break;
6754+ case INTERPOSE_REVAL:
6755+ /* Do nothing. */
6756+ break;
6757+ default:
6758+ printk(KERN_CRIT "unionfs: invalid interpose flag passed!\n");
6759+ BUG();
6760+ }
6761+ goto out;
6762+
6763+out_spliced:
6764+ if (!err)
6765+ return spliced;
6766+out:
6767+ return ERR_PTR(err);
6768+}
6769+
6770+/* like interpose above, but for an already existing dentry */
6771+void unionfs_reinterpose(struct dentry *dentry)
6772+{
6773+ struct dentry *lower_dentry;
6774+ struct inode *inode;
6775+ int bindex, bstart, bend;
6776+
6777+ verify_locked(dentry);
6778+
6779+ /* This is pre-allocated inode */
6780+ inode = dentry->d_inode;
6781+
6782+ bstart = dbstart(dentry);
6783+ bend = dbend(dentry);
6784+ for (bindex = bstart; bindex <= bend; bindex++) {
6785+ lower_dentry = unionfs_lower_dentry_idx(dentry, bindex);
6786+ if (!lower_dentry)
6787+ continue;
6788+
6789+ if (!lower_dentry->d_inode)
6790+ continue;
6791+ if (unionfs_lower_inode_idx(inode, bindex))
6792+ continue;
6793+ unionfs_set_lower_inode_idx(inode, bindex,
6794+ igrab(lower_dentry->d_inode));
6795+ }
6796+ ibstart(inode) = dbstart(dentry);
6797+ ibend(inode) = dbend(dentry);
6798+}
6799+
6800+/*
6801+ * make sure the branch we just looked up (nd) makes sense:
6802+ *
6803+ * 1) we're not trying to stack unionfs on top of unionfs
6804+ * 2) it exists
6805+ * 3) is a directory
6806+ */
6807+int check_branch(struct nameidata *nd)
6808+{
6809+ /* XXX: remove in ODF code -- stacking unions allowed there */
6810+ if (!strcmp(nd->path.dentry->d_sb->s_type->name, UNIONFS_NAME))
6811+ return -EINVAL;
6812+ if (!nd->path.dentry->d_inode)
6813+ return -ENOENT;
6814+ if (!S_ISDIR(nd->path.dentry->d_inode->i_mode))
6815+ return -ENOTDIR;
6816+ return 0;
6817+}
6818+
6819+/* checks if two lower_dentries have overlapping branches */
6820+static int is_branch_overlap(struct dentry *dent1, struct dentry *dent2)
6821+{
6822+ struct dentry *dent = NULL;
6823+
6824+ dent = dent1;
6825+ while ((dent != dent2) && (dent->d_parent != dent))
6826+ dent = dent->d_parent;
6827+
6828+ if (dent == dent2)
6829+ return 1;
6830+
6831+ dent = dent2;
6832+ while ((dent != dent1) && (dent->d_parent != dent))
6833+ dent = dent->d_parent;
6834+
6835+ return (dent == dent1);
6836+}
6837+
6838+/*
6839+ * Parse "ro" or "rw" options, but default to "rw" if no mode options was
6840+ * specified. Fill the mode bits in @perms. If encounter an unknown
6841+ * string, return -EINVAL. Otherwise return 0.
6842+ */
6843+int parse_branch_mode(const char *name, int *perms)
6844+{
6845+ if (!name || !strcmp(name, "rw")) {
6846+ *perms = MAY_READ | MAY_WRITE;
6847+ return 0;
6848+ }
6849+ if (!strcmp(name, "ro")) {
6850+ *perms = MAY_READ;
6851+ return 0;
6852+ }
6853+ return -EINVAL;
6854+}
6855+
6856+/*
6857+ * parse the dirs= mount argument
6858+ *
6859+ * We don't need to lock the superblock private data's rwsem, as we get
6860+ * called only by unionfs_read_super - it is still a long time before anyone
6861+ * can even get a reference to us.
6862+ */
6863+static int parse_dirs_option(struct super_block *sb, struct unionfs_dentry_info
6864+ *lower_root_info, char *options)
6865+{
6866+ struct nameidata nd;
6867+ char *name;
6868+ int err = 0;
6869+ int branches = 1;
6870+ int bindex = 0;
6871+ int i = 0;
6872+ int j = 0;
6873+ struct dentry *dent1;
6874+ struct dentry *dent2;
6875+
6876+ if (options[0] == '\0') {
6877+ printk(KERN_ERR "unionfs: no branches specified\n");
6878+ err = -EINVAL;
6879+ goto out;
6880+ }
6881+
6882+ /*
6883+ * Each colon means we have a separator, this is really just a rough
6884+ * guess, since strsep will handle empty fields for us.
6885+ */
6886+ for (i = 0; options[i]; i++)
6887+ if (options[i] == ':')
6888+ branches++;
6889+
6890+ /* allocate space for underlying pointers to lower dentry */
6891+ UNIONFS_SB(sb)->data =
6892+ kcalloc(branches, sizeof(struct unionfs_data), GFP_KERNEL);
6893+ if (unlikely(!UNIONFS_SB(sb)->data)) {
6894+ err = -ENOMEM;
6895+ goto out;
6896+ }
6897+
6898+ lower_root_info->lower_paths =
6899+ kcalloc(branches, sizeof(struct path), GFP_KERNEL);
6900+ if (unlikely(!lower_root_info->lower_paths)) {
6901+ err = -ENOMEM;
6902+ goto out;
6903+ }
6904+
6905+ /* now parsing a string such as "b1:b2=rw:b3=ro:b4" */
6906+ branches = 0;
6907+ while ((name = strsep(&options, ":")) != NULL) {
6908+ int perms;
6909+ char *mode = strchr(name, '=');
6910+
6911+ if (!name)
6912+ continue;
6913+ if (!*name) { /* bad use of ':' (extra colons) */
6914+ err = -EINVAL;
6915+ goto out;
6916+ }
6917+
6918+ branches++;
6919+
6920+ /* strip off '=' if any */
6921+ if (mode)
6922+ *mode++ = '\0';
6923+
6924+ err = parse_branch_mode(mode, &perms);
6925+ if (err) {
6926+ printk(KERN_ERR "unionfs: invalid mode \"%s\" for "
6927+ "branch %d\n", mode, bindex);
6928+ goto out;
6929+ }
6930+ /* ensure that leftmost branch is writeable */
6931+ if (!bindex && !(perms & MAY_WRITE)) {
6932+ printk(KERN_ERR "unionfs: leftmost branch cannot be "
6933+ "read-only (use \"-o ro\" to create a "
6934+ "read-only union)\n");
6935+ err = -EINVAL;
6936+ goto out;
6937+ }
6938+
6939+ err = path_lookup(name, LOOKUP_FOLLOW, &nd);
6940+ if (err) {
6941+ printk(KERN_ERR "unionfs: error accessing "
6942+ "lower directory '%s' (error %d)\n",
6943+ name, err);
6944+ goto out;
6945+ }
6946+
6947+ err = check_branch(&nd);
6948+ if (err) {
6949+ printk(KERN_ERR "unionfs: lower directory "
6950+ "'%s' is not a valid branch\n", name);
6951+ path_put(&nd.path);
6952+ goto out;
6953+ }
6954+
6955+ lower_root_info->lower_paths[bindex].dentry = nd.path.dentry;
6956+ lower_root_info->lower_paths[bindex].mnt = nd.path.mnt;
6957+
6958+ set_branchperms(sb, bindex, perms);
6959+ set_branch_count(sb, bindex, 0);
6960+ new_branch_id(sb, bindex);
6961+
6962+ if (lower_root_info->bstart < 0)
6963+ lower_root_info->bstart = bindex;
6964+ lower_root_info->bend = bindex;
6965+ bindex++;
6966+ }
6967+
6968+ if (branches == 0) {
6969+ printk(KERN_ERR "unionfs: no branches specified\n");
6970+ err = -EINVAL;
6971+ goto out;
6972+ }
6973+
6974+ BUG_ON(branches != (lower_root_info->bend + 1));
6975+
6976+ /*
6977+ * Ensure that no overlaps exist in the branches.
6978+ *
6979+ * This test is required because the Linux kernel has no support
6980+ * currently for ensuring coherency between stackable layers and
6981+ * branches. If we were to allow overlapping branches, it would be
6982+ * possible, for example, to delete a file via one branch, which
6983+ * would not be reflected in another branch. Such incoherency could
6984+ * lead to inconsistencies and even kernel oopses. Rather than
6985+ * implement hacks to work around some of these cache-coherency
6986+ * problems, we prevent branch overlapping, for now. A complete
6987+ * solution will involve proper kernel/VFS support for cache
6988+ * coherency, at which time we could safely remove this
6989+ * branch-overlapping test.
6990+ */
6991+ for (i = 0; i < branches; i++) {
6992+ dent1 = lower_root_info->lower_paths[i].dentry;
6993+ for (j = i + 1; j < branches; j++) {
6994+ dent2 = lower_root_info->lower_paths[j].dentry;
6995+ if (is_branch_overlap(dent1, dent2)) {
6996+ printk(KERN_ERR "unionfs: branches %d and "
6997+ "%d overlap\n", i, j);
6998+ err = -EINVAL;
6999+ goto out;
7000+ }
7001+ }
7002+ }
7003+
7004+out:
7005+ if (err) {
7006+ for (i = 0; i < branches; i++)
7007+ if (lower_root_info->lower_paths[i].dentry) {
7008+ dput(lower_root_info->lower_paths[i].dentry);
7009+ /* initialize: can't use unionfs_mntput here */
7010+ mntput(lower_root_info->lower_paths[i].mnt);
7011+ }
7012+
7013+ kfree(lower_root_info->lower_paths);
7014+ kfree(UNIONFS_SB(sb)->data);
7015+
7016+ /*
7017+ * MUST clear the pointers to prevent potential double free if
7018+ * the caller dies later on
7019+ */
7020+ lower_root_info->lower_paths = NULL;
7021+ UNIONFS_SB(sb)->data = NULL;
7022+ }
7023+ return err;
7024+}
7025+
7026+/*
7027+ * Parse mount options. See the manual page for usage instructions.
7028+ *
7029+ * Returns the dentry object of the lower-level (lower) directory;
7030+ * We want to mount our stackable file system on top of that lower directory.
7031+ */
7032+static struct unionfs_dentry_info *unionfs_parse_options(
7033+ struct super_block *sb,
7034+ char *options)
7035+{
7036+ struct unionfs_dentry_info *lower_root_info;
7037+ char *optname;
7038+ int err = 0;
7039+ int bindex;
7040+ int dirsfound = 0;
7041+
7042+ /* allocate private data area */
7043+ err = -ENOMEM;
7044+ lower_root_info =
7045+ kzalloc(sizeof(struct unionfs_dentry_info), GFP_KERNEL);
7046+ if (unlikely(!lower_root_info))
7047+ goto out_error;
7048+ lower_root_info->bstart = -1;
7049+ lower_root_info->bend = -1;
7050+ lower_root_info->bopaque = -1;
7051+
7052+ while ((optname = strsep(&options, ",")) != NULL) {
7053+ char *optarg;
7054+
7055+ if (!optname || !*optname)
7056+ continue;
7057+
7058+ optarg = strchr(optname, '=');
7059+ if (optarg)
7060+ *optarg++ = '\0';
7061+
7062+ /*
7063+ * All of our options take an argument now. Insert ones that
7064+ * don't, above this check.
7065+ */
7066+ if (!optarg) {
7067+ printk(KERN_ERR "unionfs: %s requires an argument\n",
7068+ optname);
7069+ err = -EINVAL;
7070+ goto out_error;
7071+ }
7072+
7073+ if (!strcmp("dirs", optname)) {
7074+ if (++dirsfound > 1) {
7075+ printk(KERN_ERR
7076+ "unionfs: multiple dirs specified\n");
7077+ err = -EINVAL;
7078+ goto out_error;
7079+ }
7080+ err = parse_dirs_option(sb, lower_root_info, optarg);
7081+ if (err)
7082+ goto out_error;
7083+ continue;
7084+ }
7085+
7086+ err = -EINVAL;
7087+ printk(KERN_ERR
7088+ "unionfs: unrecognized option '%s'\n", optname);
7089+ goto out_error;
7090+ }
7091+ if (dirsfound != 1) {
7092+ printk(KERN_ERR "unionfs: dirs option required\n");
7093+ err = -EINVAL;
7094+ goto out_error;
7095+ }
7096+ goto out;
7097+
7098+out_error:
7099+ if (lower_root_info && lower_root_info->lower_paths) {
7100+ for (bindex = lower_root_info->bstart;
7101+ bindex >= 0 && bindex <= lower_root_info->bend;
7102+ bindex++) {
7103+ struct dentry *d;
7104+ struct vfsmount *m;
7105+
7106+ d = lower_root_info->lower_paths[bindex].dentry;
7107+ m = lower_root_info->lower_paths[bindex].mnt;
7108+
7109+ dput(d);
7110+ /* initializing: can't use unionfs_mntput here */
7111+ mntput(m);
7112+ }
7113+ }
7114+
7115+ kfree(lower_root_info->lower_paths);
7116+ kfree(lower_root_info);
7117+
7118+ kfree(UNIONFS_SB(sb)->data);
7119+ UNIONFS_SB(sb)->data = NULL;
7120+
7121+ lower_root_info = ERR_PTR(err);
7122+out:
7123+ return lower_root_info;
7124+}
7125+
7126+/*
7127+ * our custom d_alloc_root work-alike
7128+ *
7129+ * we can't use d_alloc_root if we want to use our own interpose function
7130+ * unchanged, so we simply call our own "fake" d_alloc_root
7131+ */
7132+static struct dentry *unionfs_d_alloc_root(struct super_block *sb)
7133+{
7134+ struct dentry *ret = NULL;
7135+
7136+ if (sb) {
7137+ static const struct qstr name = {
7138+ .name = "/",
7139+ .len = 1
7140+ };
7141+
7142+ ret = d_alloc(NULL, &name);
7143+ if (likely(ret)) {
7144+ ret->d_op = &unionfs_dops;
7145+ ret->d_sb = sb;
7146+ ret->d_parent = ret;
7147+ }
7148+ }
7149+ return ret;
7150+}
7151+
7152+/*
7153+ * There is no need to lock the unionfs_super_info's rwsem as there is no
7154+ * way anyone can have a reference to the superblock at this point in time.
7155+ */
7156+static int unionfs_read_super(struct super_block *sb, void *raw_data,
7157+ int silent)
7158+{
7159+ int err = 0;
7160+ struct unionfs_dentry_info *lower_root_info = NULL;
7161+ int bindex, bstart, bend;
7162+
7163+ if (!raw_data) {
7164+ printk(KERN_ERR
7165+ "unionfs: read_super: missing data argument\n");
7166+ err = -EINVAL;
7167+ goto out;
7168+ }
7169+
7170+ /* Allocate superblock private data */
7171+ sb->s_fs_info = kzalloc(sizeof(struct unionfs_sb_info), GFP_KERNEL);
7172+ if (unlikely(!UNIONFS_SB(sb))) {
7173+ printk(KERN_CRIT "unionfs: read_super: out of memory\n");
7174+ err = -ENOMEM;
7175+ goto out;
7176+ }
7177+
7178+ UNIONFS_SB(sb)->bend = -1;
7179+ atomic_set(&UNIONFS_SB(sb)->generation, 1);
7180+ init_rwsem(&UNIONFS_SB(sb)->rwsem);
7181+ UNIONFS_SB(sb)->high_branch_id = -1; /* -1 == invalid branch ID */
7182+
7183+ lower_root_info = unionfs_parse_options(sb, raw_data);
7184+ if (IS_ERR(lower_root_info)) {
7185+ printk(KERN_ERR
7186+ "unionfs: read_super: error while parsing options "
7187+ "(err = %ld)\n", PTR_ERR(lower_root_info));
7188+ err = PTR_ERR(lower_root_info);
7189+ lower_root_info = NULL;
7190+ goto out_free;
7191+ }
7192+ if (lower_root_info->bstart == -1) {
7193+ err = -ENOENT;
7194+ goto out_free;
7195+ }
7196+
7197+ /* set the lower superblock field of upper superblock */
7198+ bstart = lower_root_info->bstart;
7199+ BUG_ON(bstart != 0);
7200+ sbend(sb) = bend = lower_root_info->bend;
7201+ for (bindex = bstart; bindex <= bend; bindex++) {
7202+ struct dentry *d = lower_root_info->lower_paths[bindex].dentry;
7203+ atomic_inc(&d->d_sb->s_active);
7204+ unionfs_set_lower_super_idx(sb, bindex, d->d_sb);
7205+ }
7206+
7207+ /* max Bytes is the maximum bytes from highest priority branch */
7208+ sb->s_maxbytes = unionfs_lower_super_idx(sb, 0)->s_maxbytes;
7209+
7210+ /*
7211+ * Our c/m/atime granularity is 1 ns because we may stack on file
7212+ * systems whose granularity is as good. This is important for our
7213+ * time-based cache coherency.
7214+ */
7215+ sb->s_time_gran = 1;
7216+
7217+ sb->s_op = &unionfs_sops;
7218+
7219+ /* See comment next to the definition of unionfs_d_alloc_root */
7220+ sb->s_root = unionfs_d_alloc_root(sb);
7221+ if (unlikely(!sb->s_root)) {
7222+ err = -ENOMEM;
7223+ goto out_dput;
7224+ }
7225+
7226+ /* link the upper and lower dentries */
7227+ sb->s_root->d_fsdata = NULL;
7228+ err = new_dentry_private_data(sb->s_root, UNIONFS_DMUTEX_ROOT);
7229+ if (unlikely(err))
7230+ goto out_freedpd;
7231+
7232+ /* Set the lower dentries for s_root */
7233+ for (bindex = bstart; bindex <= bend; bindex++) {
7234+ struct dentry *d;
7235+ struct vfsmount *m;
7236+
7237+ d = lower_root_info->lower_paths[bindex].dentry;
7238+ m = lower_root_info->lower_paths[bindex].mnt;
7239+
7240+ unionfs_set_lower_dentry_idx(sb->s_root, bindex, d);
7241+ unionfs_set_lower_mnt_idx(sb->s_root, bindex, m);
7242+ }
7243+ dbstart(sb->s_root) = bstart;
7244+ dbend(sb->s_root) = bend;
7245+
7246+ /* Set the generation number to one, since this is for the mount. */
7247+ atomic_set(&UNIONFS_D(sb->s_root)->generation, 1);
7248+
7249+ /*
7250+ * Call interpose to create the upper level inode. Only
7251+ * INTERPOSE_LOOKUP can return a value other than 0 on err.
7252+ */
7253+ err = PTR_ERR(unionfs_interpose(sb->s_root, sb, 0));
7254+ unionfs_unlock_dentry(sb->s_root);
7255+ if (!err)
7256+ goto out;
7257+ /* else fall through */
7258+
7259+out_freedpd:
7260+ if (UNIONFS_D(sb->s_root)) {
7261+ kfree(UNIONFS_D(sb->s_root)->lower_paths);
7262+ free_dentry_private_data(sb->s_root);
7263+ }
7264+ dput(sb->s_root);
7265+
7266+out_dput:
7267+ if (lower_root_info && !IS_ERR(lower_root_info)) {
7268+ for (bindex = lower_root_info->bstart;
7269+ bindex <= lower_root_info->bend; bindex++) {
7270+ struct dentry *d;
7271+ struct vfsmount *m;
7272+
7273+ d = lower_root_info->lower_paths[bindex].dentry;
7274+ m = lower_root_info->lower_paths[bindex].mnt;
7275+
7276+ dput(d);
7277+ /* initializing: can't use unionfs_mntput here */
7278+ mntput(m);
7279+ /* drop refs we took earlier */
7280+ atomic_dec(&d->d_sb->s_active);
7281+ }
7282+ kfree(lower_root_info->lower_paths);
7283+ kfree(lower_root_info);
7284+ lower_root_info = NULL;
7285+ }
7286+
7287+out_free:
7288+ kfree(UNIONFS_SB(sb)->data);
7289+ kfree(UNIONFS_SB(sb));
7290+ sb->s_fs_info = NULL;
7291+
7292+out:
7293+ if (lower_root_info && !IS_ERR(lower_root_info)) {
7294+ kfree(lower_root_info->lower_paths);
7295+ kfree(lower_root_info);
7296+ }
7297+ return err;
7298+}
7299+
7300+static int unionfs_get_sb(struct file_system_type *fs_type,
7301+ int flags, const char *dev_name,
7302+ void *raw_data, struct vfsmount *mnt)
7303+{
7304+ int err;
7305+ err = get_sb_nodev(fs_type, flags, raw_data, unionfs_read_super, mnt);
7306+ if (!err)
7307+ UNIONFS_SB(mnt->mnt_sb)->dev_name =
7308+ kstrdup(dev_name, GFP_KERNEL);
7309+ return err;
7310+}
7311+
7312+static struct file_system_type unionfs_fs_type = {
7313+ .owner = THIS_MODULE,
7314+ .name = UNIONFS_NAME,
7315+ .get_sb = unionfs_get_sb,
7316+ .kill_sb = generic_shutdown_super,
7317+ .fs_flags = FS_REVAL_DOT,
7318+};
7319+
7320+static int __init init_unionfs_fs(void)
7321+{
7322+ int err;
7323+
7324+ pr_info("Registering unionfs " UNIONFS_VERSION "\n");
7325+
7326+ err = unionfs_init_filldir_cache();
7327+ if (unlikely(err))
7328+ goto out;
7329+ err = unionfs_init_inode_cache();
7330+ if (unlikely(err))
7331+ goto out;
7332+ err = unionfs_init_dentry_cache();
7333+ if (unlikely(err))
7334+ goto out;
7335+ err = init_sioq();
7336+ if (unlikely(err))
7337+ goto out;
7338+ err = register_filesystem(&unionfs_fs_type);
7339+out:
7340+ if (unlikely(err)) {
7341+ stop_sioq();
7342+ unionfs_destroy_filldir_cache();
7343+ unionfs_destroy_inode_cache();
7344+ unionfs_destroy_dentry_cache();
7345+ }
7346+ return err;
7347+}
7348+
7349+static void __exit exit_unionfs_fs(void)
7350+{
7351+ stop_sioq();
7352+ unionfs_destroy_filldir_cache();
7353+ unionfs_destroy_inode_cache();
7354+ unionfs_destroy_dentry_cache();
7355+ unregister_filesystem(&unionfs_fs_type);
7356+ pr_info("Completed unionfs module unload\n");
7357+}
7358+
7359+MODULE_AUTHOR("Erez Zadok, Filesystems and Storage Lab, Stony Brook University"
7360+ " (http://www.fsl.cs.sunysb.edu)");
7361+MODULE_DESCRIPTION("Unionfs " UNIONFS_VERSION
7362+ " (http://unionfs.filesystems.org)");
7363+MODULE_LICENSE("GPL");
7364+
7365+module_init(init_unionfs_fs);
7366+module_exit(exit_unionfs_fs);
7367diff --git a/fs/unionfs/mmap.c b/fs/unionfs/mmap.c
7368new file mode 100644
7369index 0000000..b7d4713
7370--- /dev/null
7371+++ b/fs/unionfs/mmap.c
7372@@ -0,0 +1,89 @@
7373+/*
7374+ * Copyright (c) 2003-2008 Erez Zadok
7375+ * Copyright (c) 2003-2006 Charles P. Wright
7376+ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
7377+ * Copyright (c) 2005-2006 Junjiro Okajima
7378+ * Copyright (c) 2006 Shaya Potter
7379+ * Copyright (c) 2005 Arun M. Krishnakumar
7380+ * Copyright (c) 2004-2006 David P. Quigley
7381+ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
7382+ * Copyright (c) 2003 Puja Gupta
7383+ * Copyright (c) 2003 Harikesavan Krishnan
7384+ * Copyright (c) 2003-2008 Stony Brook University
7385+ * Copyright (c) 2003-2008 The Research Foundation of SUNY
7386+ *
7387+ * This program is free software; you can redistribute it and/or modify
7388+ * it under the terms of the GNU General Public License version 2 as
7389+ * published by the Free Software Foundation.
7390+ */
7391+
7392+#include "union.h"
7393+
7394+
7395+/*
7396+ * XXX: we need a dummy readpage handler because generic_file_mmap (which we
7397+ * use in unionfs_mmap) checks for the existence of
7398+ * mapping->a_ops->readpage, else it returns -ENOEXEC. The VFS will need to
7399+ * be fixed to allow a file system to define vm_ops->fault without any
7400+ * address_space_ops whatsoever.
7401+ *
7402+ * Otherwise, we don't want to use our readpage method at all.
7403+ */
7404+static int unionfs_readpage(struct file *file, struct page *page)
7405+{
7406+ BUG();
7407+ return -EINVAL;
7408+}
7409+
7410+static int unionfs_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
7411+{
7412+ int err;
7413+ struct file *file, *lower_file;
7414+ struct vm_operations_struct *lower_vm_ops;
7415+ struct vm_area_struct lower_vma;
7416+
7417+ BUG_ON(!vma);
7418+ memcpy(&lower_vma, vma, sizeof(struct vm_area_struct));
7419+ file = lower_vma.vm_file;
7420+ lower_vm_ops = UNIONFS_F(file)->lower_vm_ops;
7421+ BUG_ON(!lower_vm_ops);
7422+
7423+ lower_file = unionfs_lower_file(file);
7424+ BUG_ON(!lower_file);
7425+ /*
7426+ * XXX: vm_ops->fault may be called in parallel. Because we have to
7427+ * resort to temporarily changing the vma->vm_file to point to the
7428+ * lower file, a concurrent invocation of unionfs_fault could see a
7429+ * different value. In this workaround, we keep a different copy of
7430+ * the vma structure in our stack, so we never expose a different
7431+ * value of the vma->vm_file called to us, even temporarily. A
7432+ * better fix would be to change the calling semantics of ->fault to
7433+ * take an explicit file pointer.
7434+ */
7435+ lower_vma.vm_file = lower_file;
7436+ err = lower_vm_ops->fault(&lower_vma, vmf);
7437+ return err;
7438+}
7439+
7440+/*
7441+ * XXX: the default address_space_ops for unionfs is empty. We cannot set
7442+ * our inode->i_mapping->a_ops to NULL because too many code paths expect
7443+ * the a_ops vector to be non-NULL.
7444+ */
7445+struct address_space_operations unionfs_aops = {
7446+ /* empty on purpose */
7447+};
7448+
7449+/*
7450+ * XXX: we need a second, dummy address_space_ops vector, to be used
7451+ * temporarily during unionfs_mmap, because the latter calls
7452+ * generic_file_mmap, which checks if ->readpage exists, else returns
7453+ * -ENOEXEC.
7454+ */
7455+struct address_space_operations unionfs_dummy_aops = {
7456+ .readpage = unionfs_readpage,
7457+};
7458+
7459+struct vm_operations_struct unionfs_vm_ops = {
7460+ .fault = unionfs_fault,
7461+};
7462diff --git a/fs/unionfs/rdstate.c b/fs/unionfs/rdstate.c
7463new file mode 100644
7464index 0000000..06d5374
7465--- /dev/null
7466+++ b/fs/unionfs/rdstate.c
7467@@ -0,0 +1,285 @@
7468+/*
7469+ * Copyright (c) 2003-2008 Erez Zadok
7470+ * Copyright (c) 2003-2006 Charles P. Wright
7471+ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
7472+ * Copyright (c) 2005-2006 Junjiro Okajima
7473+ * Copyright (c) 2005 Arun M. Krishnakumar
7474+ * Copyright (c) 2004-2006 David P. Quigley
7475+ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
7476+ * Copyright (c) 2003 Puja Gupta
7477+ * Copyright (c) 2003 Harikesavan Krishnan
7478+ * Copyright (c) 2003-2008 Stony Brook University
7479+ * Copyright (c) 2003-2008 The Research Foundation of SUNY
7480+ *
7481+ * This program is free software; you can redistribute it and/or modify
7482+ * it under the terms of the GNU General Public License version 2 as
7483+ * published by the Free Software Foundation.
7484+ */
7485+
7486+#include "union.h"
7487+
7488+/* This file contains the routines for maintaining readdir state. */
7489+
7490+/*
7491+ * There are two structures here, rdstate which is a hash table
7492+ * of the second structure which is a filldir_node.
7493+ */
7494+
7495+/*
7496+ * This is a struct kmem_cache for filldir nodes, because we allocate a lot
7497+ * of them and they shouldn't waste memory. If the node has a small name
7498+ * (as defined by the dentry structure), then we use an inline name to
7499+ * preserve kmalloc space.
7500+ */
7501+static struct kmem_cache *unionfs_filldir_cachep;
7502+
7503+int unionfs_init_filldir_cache(void)
7504+{
7505+ unionfs_filldir_cachep =
7506+ kmem_cache_create("unionfs_filldir",
7507+ sizeof(struct filldir_node), 0,
7508+ SLAB_RECLAIM_ACCOUNT, NULL);
7509+
7510+ return (unionfs_filldir_cachep ? 0 : -ENOMEM);
7511+}
7512+
7513+void unionfs_destroy_filldir_cache(void)
7514+{
7515+ if (unionfs_filldir_cachep)
7516+ kmem_cache_destroy(unionfs_filldir_cachep);
7517+}
7518+
7519+/*
7520+ * This is a tuning parameter that tells us roughly how big to make the
7521+ * hash table in directory entries per page. This isn't perfect, but
7522+ * at least we get a hash table size that shouldn't be too overloaded.
7523+ * The following averages are based on my home directory.
7524+ * 14.44693 Overall
7525+ * 12.29 Single Page Directories
7526+ * 117.93 Multi-page directories
7527+ */
7528+#define DENTPAGE 4096
7529+#define DENTPERONEPAGE 12
7530+#define DENTPERPAGE 118
7531+#define MINHASHSIZE 1
7532+static int guesstimate_hash_size(struct inode *inode)
7533+{
7534+ struct inode *lower_inode;
7535+ int bindex;
7536+ int hashsize = MINHASHSIZE;
7537+
7538+ if (UNIONFS_I(inode)->hashsize > 0)
7539+ return UNIONFS_I(inode)->hashsize;
7540+
7541+ for (bindex = ibstart(inode); bindex <= ibend(inode); bindex++) {
7542+ lower_inode = unionfs_lower_inode_idx(inode, bindex);
7543+ if (!lower_inode)
7544+ continue;
7545+
7546+ if (i_size_read(lower_inode) == DENTPAGE)
7547+ hashsize += DENTPERONEPAGE;
7548+ else
7549+ hashsize += (i_size_read(lower_inode) / DENTPAGE) *
7550+ DENTPERPAGE;
7551+ }
7552+
7553+ return hashsize;
7554+}
7555+
7556+int init_rdstate(struct file *file)
7557+{
7558+ BUG_ON(sizeof(loff_t) !=
7559+ (sizeof(unsigned int) + sizeof(unsigned int)));
7560+ BUG_ON(UNIONFS_F(file)->rdstate != NULL);
7561+
7562+ UNIONFS_F(file)->rdstate = alloc_rdstate(file->f_path.dentry->d_inode,
7563+ fbstart(file));
7564+
7565+ return (UNIONFS_F(file)->rdstate ? 0 : -ENOMEM);
7566+}
7567+
7568+struct unionfs_dir_state *find_rdstate(struct inode *inode, loff_t fpos)
7569+{
7570+ struct unionfs_dir_state *rdstate = NULL;
7571+ struct list_head *pos;
7572+
7573+ spin_lock(&UNIONFS_I(inode)->rdlock);
7574+ list_for_each(pos, &UNIONFS_I(inode)->readdircache) {
7575+ struct unionfs_dir_state *r =
7576+ list_entry(pos, struct unionfs_dir_state, cache);
7577+ if (fpos == rdstate2offset(r)) {
7578+ UNIONFS_I(inode)->rdcount--;
7579+ list_del(&r->cache);
7580+ rdstate = r;
7581+ break;
7582+ }
7583+ }
7584+ spin_unlock(&UNIONFS_I(inode)->rdlock);
7585+ return rdstate;
7586+}
7587+
7588+struct unionfs_dir_state *alloc_rdstate(struct inode *inode, int bindex)
7589+{
7590+ int i = 0;
7591+ int hashsize;
7592+ unsigned long mallocsize = sizeof(struct unionfs_dir_state);
7593+ struct unionfs_dir_state *rdstate;
7594+
7595+ hashsize = guesstimate_hash_size(inode);
7596+ mallocsize += hashsize * sizeof(struct list_head);
7597+ mallocsize = __roundup_pow_of_two(mallocsize);
7598+
7599+ /* This should give us about 500 entries anyway. */
7600+ if (mallocsize > PAGE_SIZE)
7601+ mallocsize = PAGE_SIZE;
7602+
7603+ hashsize = (mallocsize - sizeof(struct unionfs_dir_state)) /
7604+ sizeof(struct list_head);
7605+
7606+ rdstate = kmalloc(mallocsize, GFP_KERNEL);
7607+ if (unlikely(!rdstate))
7608+ return NULL;
7609+
7610+ spin_lock(&UNIONFS_I(inode)->rdlock);
7611+ if (UNIONFS_I(inode)->cookie >= (MAXRDCOOKIE - 1))
7612+ UNIONFS_I(inode)->cookie = 1;
7613+ else
7614+ UNIONFS_I(inode)->cookie++;
7615+
7616+ rdstate->cookie = UNIONFS_I(inode)->cookie;
7617+ spin_unlock(&UNIONFS_I(inode)->rdlock);
7618+ rdstate->offset = 1;
7619+ rdstate->access = jiffies;
7620+ rdstate->bindex = bindex;
7621+ rdstate->dirpos = 0;
7622+ rdstate->hashentries = 0;
7623+ rdstate->size = hashsize;
7624+ for (i = 0; i < rdstate->size; i++)
7625+ INIT_LIST_HEAD(&rdstate->list[i]);
7626+
7627+ return rdstate;
7628+}
7629+
7630+static void free_filldir_node(struct filldir_node *node)
7631+{
7632+ if (node->namelen >= DNAME_INLINE_LEN_MIN)
7633+ kfree(node->name);
7634+ kmem_cache_free(unionfs_filldir_cachep, node);
7635+}
7636+
7637+void free_rdstate(struct unionfs_dir_state *state)
7638+{
7639+ struct filldir_node *tmp;
7640+ int i;
7641+
7642+ for (i = 0; i < state->size; i++) {
7643+ struct list_head *head = &(state->list[i]);
7644+ struct list_head *pos, *n;
7645+
7646+ /* traverse the list and deallocate space */
7647+ list_for_each_safe(pos, n, head) {
7648+ tmp = list_entry(pos, struct filldir_node, file_list);
7649+ list_del(&tmp->file_list);
7650+ free_filldir_node(tmp);
7651+ }
7652+ }
7653+
7654+ kfree(state);
7655+}
7656+
7657+struct filldir_node *find_filldir_node(struct unionfs_dir_state *rdstate,
7658+ const char *name, int namelen,
7659+ int is_whiteout)
7660+{
7661+ int index;
7662+ unsigned int hash;
7663+ struct list_head *head;
7664+ struct list_head *pos;
7665+ struct filldir_node *cursor = NULL;
7666+ int found = 0;
7667+
7668+ BUG_ON(namelen <= 0);
7669+
7670+ hash = full_name_hash(name, namelen);
7671+ index = hash % rdstate->size;
7672+
7673+ head = &(rdstate->list[index]);
7674+ list_for_each(pos, head) {
7675+ cursor = list_entry(pos, struct filldir_node, file_list);
7676+
7677+ if (cursor->namelen == namelen && cursor->hash == hash &&
7678+ !strncmp(cursor->name, name, namelen)) {
7679+ /*
7680+ * a duplicate exists, and hence no need to create
7681+ * entry to the list
7682+ */
7683+ found = 1;
7684+
7685+ /*
7686+ * if a duplicate is found in this branch, and is
7687+ * not due to the caller looking for an entry to
7688+ * whiteout, then the file system may be corrupted.
7689+ */
7690+ if (unlikely(!is_whiteout &&
7691+ cursor->bindex == rdstate->bindex))
7692+ printk(KERN_ERR "unionfs: filldir: possible "
7693+ "I/O error: a file is duplicated "
7694+ "in the same branch %d: %s\n",
7695+ rdstate->bindex, cursor->name);
7696+ break;
7697+ }
7698+ }
7699+
7700+ if (!found)
7701+ cursor = NULL;
7702+
7703+ return cursor;
7704+}
7705+
7706+int add_filldir_node(struct unionfs_dir_state *rdstate, const char *name,
7707+ int namelen, int bindex, int whiteout)
7708+{
7709+ struct filldir_node *new;
7710+ unsigned int hash;
7711+ int index;
7712+ int err = 0;
7713+ struct list_head *head;
7714+
7715+ BUG_ON(namelen <= 0);
7716+
7717+ hash = full_name_hash(name, namelen);
7718+ index = hash % rdstate->size;
7719+ head = &(rdstate->list[index]);
7720+
7721+ new = kmem_cache_alloc(unionfs_filldir_cachep, GFP_KERNEL);
7722+ if (unlikely(!new)) {
7723+ err = -ENOMEM;
7724+ goto out;
7725+ }
7726+
7727+ INIT_LIST_HEAD(&new->file_list);
7728+ new->namelen = namelen;
7729+ new->hash = hash;
7730+ new->bindex = bindex;
7731+ new->whiteout = whiteout;
7732+
7733+ if (namelen < DNAME_INLINE_LEN_MIN) {
7734+ new->name = new->iname;
7735+ } else {
7736+ new->name = kmalloc(namelen + 1, GFP_KERNEL);
7737+ if (unlikely(!new->name)) {
7738+ kmem_cache_free(unionfs_filldir_cachep, new);
7739+ new = NULL;
7740+ goto out;
7741+ }
7742+ }
7743+
7744+ memcpy(new->name, name, namelen);
7745+ new->name[namelen] = '\0';
7746+
7747+ rdstate->hashentries++;
7748+
7749+ list_add(&(new->file_list), head);
7750+out:
7751+ return err;
7752+}
7753diff --git a/fs/unionfs/rename.c b/fs/unionfs/rename.c
7754new file mode 100644
7755index 0000000..da7d589
7756--- /dev/null
7757+++ b/fs/unionfs/rename.c
7758@@ -0,0 +1,478 @@
7759+/*
7760+ * Copyright (c) 2003-2008 Erez Zadok
7761+ * Copyright (c) 2003-2006 Charles P. Wright
7762+ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
7763+ * Copyright (c) 2005-2006 Junjiro Okajima
7764+ * Copyright (c) 2005 Arun M. Krishnakumar
7765+ * Copyright (c) 2004-2006 David P. Quigley
7766+ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
7767+ * Copyright (c) 2003 Puja Gupta
7768+ * Copyright (c) 2003 Harikesavan Krishnan
7769+ * Copyright (c) 2003-2008 Stony Brook University
7770+ * Copyright (c) 2003-2008 The Research Foundation of SUNY
7771+ *
7772+ * This program is free software; you can redistribute it and/or modify
7773+ * it under the terms of the GNU General Public License version 2 as
7774+ * published by the Free Software Foundation.
7775+ */
7776+
7777+#include "union.h"
7778+
7779+/*
7780+ * This is a helper function for rename, used when rename ends up with hosed
7781+ * over dentries and we need to revert.
7782+ */
7783+static int unionfs_refresh_lower_dentry(struct dentry *dentry, int bindex)
7784+{
7785+ struct dentry *lower_dentry;
7786+ struct dentry *lower_parent;
7787+ int err = 0;
7788+
7789+ verify_locked(dentry);
7790+
7791+ unionfs_lock_dentry(dentry->d_parent, UNIONFS_DMUTEX_CHILD);
7792+ lower_parent = unionfs_lower_dentry_idx(dentry->d_parent, bindex);
7793+ unionfs_unlock_dentry(dentry->d_parent);
7794+
7795+ BUG_ON(!S_ISDIR(lower_parent->d_inode->i_mode));
7796+
7797+ lower_dentry = lookup_one_len(dentry->d_name.name, lower_parent,
7798+ dentry->d_name.len);
7799+ if (IS_ERR(lower_dentry)) {
7800+ err = PTR_ERR(lower_dentry);
7801+ goto out;
7802+ }
7803+
7804+ dput(unionfs_lower_dentry_idx(dentry, bindex));
7805+ iput(unionfs_lower_inode_idx(dentry->d_inode, bindex));
7806+ unionfs_set_lower_inode_idx(dentry->d_inode, bindex, NULL);
7807+
7808+ if (!lower_dentry->d_inode) {
7809+ dput(lower_dentry);
7810+ unionfs_set_lower_dentry_idx(dentry, bindex, NULL);
7811+ } else {
7812+ unionfs_set_lower_dentry_idx(dentry, bindex, lower_dentry);
7813+ unionfs_set_lower_inode_idx(dentry->d_inode, bindex,
7814+ igrab(lower_dentry->d_inode));
7815+ }
7816+
7817+out:
7818+ return err;
7819+}
7820+
7821+static int __unionfs_rename(struct inode *old_dir, struct dentry *old_dentry,
7822+ struct inode *new_dir, struct dentry *new_dentry,
7823+ int bindex)
7824+{
7825+ int err = 0;
7826+ struct dentry *lower_old_dentry;
7827+ struct dentry *lower_new_dentry;
7828+ struct dentry *lower_old_dir_dentry;
7829+ struct dentry *lower_new_dir_dentry;
7830+ struct dentry *trap;
7831+
7832+ lower_new_dentry = unionfs_lower_dentry_idx(new_dentry, bindex);
7833+ lower_old_dentry = unionfs_lower_dentry_idx(old_dentry, bindex);
7834+
7835+ if (!lower_new_dentry) {
7836+ lower_new_dentry =
7837+ create_parents(new_dentry->d_parent->d_inode,
7838+ new_dentry, new_dentry->d_name.name,
7839+ bindex);
7840+ if (IS_ERR(lower_new_dentry)) {
7841+ err = PTR_ERR(lower_new_dentry);
7842+ if (IS_COPYUP_ERR(err))
7843+ goto out;
7844+ printk(KERN_ERR "unionfs: error creating directory "
7845+ "tree for rename, bindex=%d err=%d\n",
7846+ bindex, err);
7847+ goto out;
7848+ }
7849+ }
7850+
7851+ /* check for and remove whiteout, if any */
7852+ err = check_unlink_whiteout(new_dentry, lower_new_dentry, bindex);
7853+ if (err > 0) /* ignore if whiteout found and successfully removed */
7854+ err = 0;
7855+ if (err)
7856+ goto out;
7857+
7858+ /* check of old_dentry branch is writable */
7859+ err = is_robranch_super(old_dentry->d_sb, bindex);
7860+ if (err)
7861+ goto out;
7862+
7863+ dget(lower_old_dentry);
7864+ dget(lower_new_dentry);
7865+ lower_old_dir_dentry = dget_parent(lower_old_dentry);
7866+ lower_new_dir_dentry = dget_parent(lower_new_dentry);
7867+
7868+ /* see Documentation/filesystems/unionfs/issues.txt */
7869+ lockdep_off();
7870+ trap = lock_rename(lower_old_dir_dentry, lower_new_dir_dentry);
7871+ /* source should not be ancenstor of target */
7872+ if (trap == lower_old_dentry) {
7873+ err = -EINVAL;
7874+ goto out_err_unlock;
7875+ }
7876+ /* target should not be ancenstor of source */
7877+ if (trap == lower_new_dentry) {
7878+ err = -ENOTEMPTY;
7879+ goto out_err_unlock;
7880+ }
7881+ err = vfs_rename(lower_old_dir_dentry->d_inode, lower_old_dentry,
7882+ lower_new_dir_dentry->d_inode, lower_new_dentry);
7883+out_err_unlock:
7884+ if (!err) {
7885+ /* update parent dir times */
7886+ fsstack_copy_attr_times(old_dir, lower_old_dir_dentry->d_inode);
7887+ fsstack_copy_attr_times(new_dir, lower_new_dir_dentry->d_inode);
7888+ }
7889+ unlock_rename(lower_old_dir_dentry, lower_new_dir_dentry);
7890+ lockdep_on();
7891+
7892+ dput(lower_old_dir_dentry);
7893+ dput(lower_new_dir_dentry);
7894+ dput(lower_old_dentry);
7895+ dput(lower_new_dentry);
7896+
7897+out:
7898+ if (!err) {
7899+ /* Fixup the new_dentry. */
7900+ if (bindex < dbstart(new_dentry))
7901+ dbstart(new_dentry) = bindex;
7902+ else if (bindex > dbend(new_dentry))
7903+ dbend(new_dentry) = bindex;
7904+ }
7905+
7906+ return err;
7907+}
7908+
7909+/*
7910+ * Main rename code. This is sufficiently complex, that it's documented in
7911+ * Documentation/filesystems/unionfs/rename.txt. This routine calls
7912+ * __unionfs_rename() above to perform some of the work.
7913+ */
7914+static int do_unionfs_rename(struct inode *old_dir,
7915+ struct dentry *old_dentry,
7916+ struct inode *new_dir,
7917+ struct dentry *new_dentry)
7918+{
7919+ int err = 0;
7920+ int bindex, bwh_old;
7921+ int old_bstart, old_bend;
7922+ int new_bstart, new_bend;
7923+ int do_copyup = -1;
7924+ struct dentry *parent_dentry;
7925+ int local_err = 0;
7926+ int eio = 0;
7927+ int revert = 0;
7928+
7929+ old_bstart = dbstart(old_dentry);
7930+ bwh_old = old_bstart;
7931+ old_bend = dbend(old_dentry);
7932+ parent_dentry = old_dentry->d_parent;
7933+
7934+ new_bstart = dbstart(new_dentry);
7935+ new_bend = dbend(new_dentry);
7936+
7937+ /* Rename source to destination. */
7938+ err = __unionfs_rename(old_dir, old_dentry, new_dir, new_dentry,
7939+ old_bstart);
7940+ if (err) {
7941+ if (!IS_COPYUP_ERR(err))
7942+ goto out;
7943+ do_copyup = old_bstart - 1;
7944+ } else {
7945+ revert = 1;
7946+ }
7947+
7948+ /*
7949+ * Unlink all instances of destination that exist to the left of
7950+ * bstart of source. On error, revert back, goto out.
7951+ */
7952+ for (bindex = old_bstart - 1; bindex >= new_bstart; bindex--) {
7953+ struct dentry *unlink_dentry;
7954+ struct dentry *unlink_dir_dentry;
7955+
7956+ BUG_ON(bindex < 0);
7957+ unlink_dentry = unionfs_lower_dentry_idx(new_dentry, bindex);
7958+ if (!unlink_dentry)
7959+ continue;
7960+
7961+ unlink_dir_dentry = lock_parent(unlink_dentry);
7962+ err = is_robranch_super(old_dir->i_sb, bindex);
7963+ if (!err)
7964+ err = vfs_unlink(unlink_dir_dentry->d_inode,
7965+ unlink_dentry);
7966+
7967+ fsstack_copy_attr_times(new_dentry->d_parent->d_inode,
7968+ unlink_dir_dentry->d_inode);
7969+ /* propagate number of hard-links */
7970+ new_dentry->d_parent->d_inode->i_nlink =
7971+ unionfs_get_nlinks(new_dentry->d_parent->d_inode);
7972+
7973+ unlock_dir(unlink_dir_dentry);
7974+ if (!err) {
7975+ if (bindex != new_bstart) {
7976+ dput(unlink_dentry);
7977+ unionfs_set_lower_dentry_idx(new_dentry,
7978+ bindex, NULL);
7979+ }
7980+ } else if (IS_COPYUP_ERR(err)) {
7981+ do_copyup = bindex - 1;
7982+ } else if (revert) {
7983+ goto revert;
7984+ }
7985+ }
7986+
7987+ if (do_copyup != -1) {
7988+ for (bindex = do_copyup; bindex >= 0; bindex--) {
7989+ /*
7990+ * copyup the file into some left directory, so that
7991+ * you can rename it
7992+ */
7993+ err = copyup_dentry(old_dentry->d_parent->d_inode,
7994+ old_dentry, old_bstart, bindex,
7995+ old_dentry->d_name.name,
7996+ old_dentry->d_name.len, NULL,
7997+ i_size_read(old_dentry->d_inode));
7998+ /* if copyup failed, try next branch to the left */
7999+ if (err)
8000+ continue;
8001+ bwh_old = bindex;
8002+ err = __unionfs_rename(old_dir, old_dentry,
8003+ new_dir, new_dentry,
8004+ bindex);
8005+ break;
8006+ }
8007+ }
8008+
8009+ /* make it opaque */
8010+ if (S_ISDIR(old_dentry->d_inode->i_mode)) {
8011+ err = make_dir_opaque(old_dentry, dbstart(old_dentry));
8012+ if (err)
8013+ goto revert;
8014+ }
8015+
8016+ /*
8017+ * Create whiteout for source, only if:
8018+ * (1) There is more than one underlying instance of source.
8019+ * (2) We did a copy_up
8020+ */
8021+ if ((old_bstart != old_bend) || (do_copyup != -1)) {
8022+ if (bwh_old < 0) {
8023+ printk(KERN_ERR "unionfs: rename error (bwh_old=%d)\n",
8024+ bwh_old);
8025+ err = -EIO;
8026+ goto out;
8027+ }
8028+ err = create_whiteout(old_dentry, bwh_old);
8029+ if (err) {
8030+ /* can't fix anything now, so we exit with -EIO */
8031+ printk(KERN_ERR "unionfs: can't create a whiteout for "
8032+ "%s in rename!\n", old_dentry->d_name.name);
8033+ err = -EIO;
8034+ }
8035+ }
8036+
8037+out:
8038+ return err;
8039+
8040+revert:
8041+ /* Do revert here. */
8042+ local_err = unionfs_refresh_lower_dentry(new_dentry, old_bstart);
8043+ if (local_err) {
8044+ printk(KERN_ERR "unionfs: revert failed in rename: "
8045+ "the new refresh failed\n");
8046+ eio = -EIO;
8047+ }
8048+
8049+ local_err = unionfs_refresh_lower_dentry(old_dentry, old_bstart);
8050+ if (local_err) {
8051+ printk(KERN_ERR "unionfs: revert failed in rename: "
8052+ "the old refresh failed\n");
8053+ eio = -EIO;
8054+ goto revert_out;
8055+ }
8056+
8057+ if (!unionfs_lower_dentry_idx(new_dentry, bindex) ||
8058+ !unionfs_lower_dentry_idx(new_dentry, bindex)->d_inode) {
8059+ printk(KERN_ERR "unionfs: revert failed in rename: "
8060+ "the object disappeared from under us!\n");
8061+ eio = -EIO;
8062+ goto revert_out;
8063+ }
8064+
8065+ if (unionfs_lower_dentry_idx(old_dentry, bindex) &&
8066+ unionfs_lower_dentry_idx(old_dentry, bindex)->d_inode) {
8067+ printk(KERN_ERR "unionfs: revert failed in rename: "
8068+ "the object was created underneath us!\n");
8069+ eio = -EIO;
8070+ goto revert_out;
8071+ }
8072+
8073+ local_err = __unionfs_rename(new_dir, new_dentry,
8074+ old_dir, old_dentry, old_bstart);
8075+
8076+ /* If we can't fix it, then we cop-out with -EIO. */
8077+ if (local_err) {
8078+ printk(KERN_ERR "unionfs: revert failed in rename!\n");
8079+ eio = -EIO;
8080+ }
8081+
8082+ local_err = unionfs_refresh_lower_dentry(new_dentry, bindex);
8083+ if (local_err)
8084+ eio = -EIO;
8085+ local_err = unionfs_refresh_lower_dentry(old_dentry, bindex);
8086+ if (local_err)
8087+ eio = -EIO;
8088+
8089+revert_out:
8090+ if (eio)
8091+ err = eio;
8092+ return err;
8093+}
8094+
8095+/*
8096+ * We can't copyup a directory, because it may involve huge numbers of
8097+ * children, etc. Doing that in the kernel would be bad, so instead we
8098+ * return EXDEV to the user-space utility that caused this, and let the
8099+ * user-space recurse and ask us to copy up each file separately.
8100+ */
8101+static int may_rename_dir(struct dentry *dentry)
8102+{
8103+ int err, bstart;
8104+
8105+ err = check_empty(dentry, NULL);
8106+ if (err == -ENOTEMPTY) {
8107+ if (is_robranch(dentry))
8108+ return -EXDEV;
8109+ } else if (err) {
8110+ return err;
8111+ }
8112+
8113+ bstart = dbstart(dentry);
8114+ if (dbend(dentry) == bstart || dbopaque(dentry) == bstart)
8115+ return 0;
8116+
8117+ dbstart(dentry) = bstart + 1;
8118+ err = check_empty(dentry, NULL);
8119+ dbstart(dentry) = bstart;
8120+ if (err == -ENOTEMPTY)
8121+ err = -EXDEV;
8122+ return err;
8123+}
8124+
8125+int unionfs_rename(struct inode *old_dir, struct dentry *old_dentry,
8126+ struct inode *new_dir, struct dentry *new_dentry)
8127+{
8128+ int err = 0;
8129+ struct dentry *wh_dentry;
8130+
8131+ unionfs_read_lock(old_dentry->d_sb, UNIONFS_SMUTEX_CHILD);
8132+ unionfs_double_lock_dentry(old_dentry, new_dentry);
8133+
8134+ if (unlikely(!__unionfs_d_revalidate_chain(old_dentry, NULL, false))) {
8135+ err = -ESTALE;
8136+ goto out;
8137+ }
8138+ if (unlikely(!d_deleted(new_dentry) && new_dentry->d_inode &&
8139+ !__unionfs_d_revalidate_chain(new_dentry, NULL, false))) {
8140+ err = -ESTALE;
8141+ goto out;
8142+ }
8143+
8144+ if (!S_ISDIR(old_dentry->d_inode->i_mode))
8145+ err = unionfs_partial_lookup(old_dentry);
8146+ else
8147+ err = may_rename_dir(old_dentry);
8148+
8149+ if (err)
8150+ goto out;
8151+
8152+ err = unionfs_partial_lookup(new_dentry);
8153+ if (err)
8154+ goto out;
8155+
8156+ /*
8157+ * if new_dentry is already lower because of whiteout,
8158+ * simply override it even if the whited-out dir is not empty.
8159+ */
8160+ wh_dentry = find_first_whiteout(new_dentry);
8161+ if (!IS_ERR(wh_dentry)) {
8162+ dput(wh_dentry);
8163+ } else if (new_dentry->d_inode) {
8164+ if (S_ISDIR(old_dentry->d_inode->i_mode) !=
8165+ S_ISDIR(new_dentry->d_inode->i_mode)) {
8166+ err = S_ISDIR(old_dentry->d_inode->i_mode) ?
8167+ -ENOTDIR : -EISDIR;
8168+ goto out;
8169+ }
8170+
8171+ if (S_ISDIR(new_dentry->d_inode->i_mode)) {
8172+ struct unionfs_dir_state *namelist = NULL;
8173+ /* check if this unionfs directory is empty or not */
8174+ err = check_empty(new_dentry, &namelist);
8175+ if (err)
8176+ goto out;
8177+
8178+ if (!is_robranch(new_dentry))
8179+ err = delete_whiteouts(new_dentry,
8180+ dbstart(new_dentry),
8181+ namelist);
8182+
8183+ free_rdstate(namelist);
8184+
8185+ if (err)
8186+ goto out;
8187+ }
8188+ }
8189+
8190+ err = do_unionfs_rename(old_dir, old_dentry, new_dir, new_dentry);
8191+ if (err)
8192+ goto out;
8193+
8194+ /*
8195+ * force re-lookup since the dir on ro branch is not renamed, and
8196+ * lower dentries still indicate the un-renamed ones.
8197+ */
8198+ if (S_ISDIR(old_dentry->d_inode->i_mode))
8199+ atomic_dec(&UNIONFS_D(old_dentry)->generation);
8200+ else
8201+ unionfs_postcopyup_release(old_dentry);
8202+ if (new_dentry->d_inode && !S_ISDIR(new_dentry->d_inode->i_mode)) {
8203+ unionfs_postcopyup_release(new_dentry);
8204+ unionfs_postcopyup_setmnt(new_dentry);
8205+ if (!unionfs_lower_inode(new_dentry->d_inode)) {
8206+ /*
8207+ * If we get here, it means that no copyup was
8208+ * needed, and that a file by the old name already
8209+ * existing on the destination branch; that file got
8210+ * renamed earlier in this function, so all we need
8211+ * to do here is set the lower inode.
8212+ */
8213+ struct inode *inode;
8214+ inode = unionfs_lower_inode(old_dentry->d_inode);
8215+ igrab(inode);
8216+ unionfs_set_lower_inode_idx(new_dentry->d_inode,
8217+ dbstart(new_dentry),
8218+ inode);
8219+ }
8220+ }
8221+ /* if all of this renaming succeeded, update our times */
8222+ unionfs_copy_attr_times(old_dentry->d_inode);
8223+ unionfs_copy_attr_times(new_dentry->d_inode);
8224+ unionfs_check_inode(old_dir);
8225+ unionfs_check_inode(new_dir);
8226+ unionfs_check_dentry(old_dentry);
8227+ unionfs_check_dentry(new_dentry);
8228+
8229+out:
8230+ if (err) /* clear the new_dentry stuff created */
8231+ d_drop(new_dentry);
8232+ unionfs_unlock_dentry(new_dentry);
8233+ unionfs_unlock_dentry(old_dentry);
8234+ unionfs_read_unlock(old_dentry->d_sb);
8235+ return err;
8236+}
8237diff --git a/fs/unionfs/sioq.c b/fs/unionfs/sioq.c
8238new file mode 100644
8239index 0000000..dd45e39
8240--- /dev/null
8241+++ b/fs/unionfs/sioq.c
8242@@ -0,0 +1,101 @@
8243+/*
8244+ * Copyright (c) 2006-2008 Erez Zadok
8245+ * Copyright (c) 2006 Charles P. Wright
8246+ * Copyright (c) 2006-2007 Josef 'Jeff' Sipek
8247+ * Copyright (c) 2006 Junjiro Okajima
8248+ * Copyright (c) 2006 David P. Quigley
8249+ * Copyright (c) 2006-2008 Stony Brook University
8250+ * Copyright (c) 2006-2008 The Research Foundation of SUNY
8251+ *
8252+ * This program is free software; you can redistribute it and/or modify
8253+ * it under the terms of the GNU General Public License version 2 as
8254+ * published by the Free Software Foundation.
8255+ */
8256+
8257+#include "union.h"
8258+
8259+/*
8260+ * Super-user IO work Queue - sometimes we need to perform actions which
8261+ * would fail due to the unix permissions on the parent directory (e.g.,
8262+ * rmdir a directory which appears empty, but in reality contains
8263+ * whiteouts).
8264+ */
8265+
8266+static struct workqueue_struct *superio_workqueue;
8267+
8268+int __init init_sioq(void)
8269+{
8270+ int err;
8271+
8272+ superio_workqueue = create_workqueue("unionfs_siod");
8273+ if (!IS_ERR(superio_workqueue))
8274+ return 0;
8275+
8276+ err = PTR_ERR(superio_workqueue);
8277+ printk(KERN_ERR "unionfs: create_workqueue failed %d\n", err);
8278+ superio_workqueue = NULL;
8279+ return err;
8280+}
8281+
8282+void stop_sioq(void)
8283+{
8284+ if (superio_workqueue)
8285+ destroy_workqueue(superio_workqueue);
8286+}
8287+
8288+void run_sioq(work_func_t func, struct sioq_args *args)
8289+{
8290+ INIT_WORK(&args->work, func);
8291+
8292+ init_completion(&args->comp);
8293+ while (!queue_work(superio_workqueue, &args->work)) {
8294+ /* TODO: do accounting if needed */
8295+ schedule();
8296+ }
8297+ wait_for_completion(&args->comp);
8298+}
8299+
8300+void __unionfs_create(struct work_struct *work)
8301+{
8302+ struct sioq_args *args = container_of(work, struct sioq_args, work);
8303+ struct create_args *c = &args->create;
8304+
8305+ args->err = vfs_create(c->parent, c->dentry, c->mode, c->nd);
8306+ complete(&args->comp);
8307+}
8308+
8309+void __unionfs_mkdir(struct work_struct *work)
8310+{
8311+ struct sioq_args *args = container_of(work, struct sioq_args, work);
8312+ struct mkdir_args *m = &args->mkdir;
8313+
8314+ args->err = vfs_mkdir(m->parent, m->dentry, m->mode);
8315+ complete(&args->comp);
8316+}
8317+
8318+void __unionfs_mknod(struct work_struct *work)
8319+{
8320+ struct sioq_args *args = container_of(work, struct sioq_args, work);
8321+ struct mknod_args *m = &args->mknod;
8322+
8323+ args->err = vfs_mknod(m->parent, m->dentry, m->mode, m->dev);
8324+ complete(&args->comp);
8325+}
8326+
8327+void __unionfs_symlink(struct work_struct *work)
8328+{
8329+ struct sioq_args *args = container_of(work, struct sioq_args, work);
8330+ struct symlink_args *s = &args->symlink;
8331+
8332+ args->err = vfs_symlink(s->parent, s->dentry, s->symbuf);
8333+ complete(&args->comp);
8334+}
8335+
8336+void __unionfs_unlink(struct work_struct *work)
8337+{
8338+ struct sioq_args *args = container_of(work, struct sioq_args, work);
8339+ struct unlink_args *u = &args->unlink;
8340+
8341+ args->err = vfs_unlink(u->parent, u->dentry);
8342+ complete(&args->comp);
8343+}
8344diff --git a/fs/unionfs/sioq.h b/fs/unionfs/sioq.h
8345new file mode 100644
8346index 0000000..679a0df
8347--- /dev/null
8348+++ b/fs/unionfs/sioq.h
8349@@ -0,0 +1,91 @@
8350+/*
8351+ * Copyright (c) 2006-2008 Erez Zadok
8352+ * Copyright (c) 2006 Charles P. Wright
8353+ * Copyright (c) 2006-2007 Josef 'Jeff' Sipek
8354+ * Copyright (c) 2006 Junjiro Okajima
8355+ * Copyright (c) 2006 David P. Quigley
8356+ * Copyright (c) 2006-2008 Stony Brook University
8357+ * Copyright (c) 2006-2008 The Research Foundation of SUNY
8358+ *
8359+ * This program is free software; you can redistribute it and/or modify
8360+ * it under the terms of the GNU General Public License version 2 as
8361+ * published by the Free Software Foundation.
8362+ */
8363+
8364+#ifndef _SIOQ_H
8365+#define _SIOQ_H
8366+
8367+struct deletewh_args {
8368+ struct unionfs_dir_state *namelist;
8369+ struct dentry *dentry;
8370+ int bindex;
8371+};
8372+
8373+struct is_opaque_args {
8374+ struct dentry *dentry;
8375+};
8376+
8377+struct create_args {
8378+ struct inode *parent;
8379+ struct dentry *dentry;
8380+ umode_t mode;
8381+ struct nameidata *nd;
8382+};
8383+
8384+struct mkdir_args {
8385+ struct inode *parent;
8386+ struct dentry *dentry;
8387+ umode_t mode;
8388+};
8389+
8390+struct mknod_args {
8391+ struct inode *parent;
8392+ struct dentry *dentry;
8393+ umode_t mode;
8394+ dev_t dev;
8395+};
8396+
8397+struct symlink_args {
8398+ struct inode *parent;
8399+ struct dentry *dentry;
8400+ char *symbuf;
8401+};
8402+
8403+struct unlink_args {
8404+ struct inode *parent;
8405+ struct dentry *dentry;
8406+};
8407+
8408+
8409+struct sioq_args {
8410+ struct completion comp;
8411+ struct work_struct work;
8412+ int err;
8413+ void *ret;
8414+
8415+ union {
8416+ struct deletewh_args deletewh;
8417+ struct is_opaque_args is_opaque;
8418+ struct create_args create;
8419+ struct mkdir_args mkdir;
8420+ struct mknod_args mknod;
8421+ struct symlink_args symlink;
8422+ struct unlink_args unlink;
8423+ };
8424+};
8425+
8426+/* Extern definitions for SIOQ functions */
8427+extern int __init init_sioq(void);
8428+extern void stop_sioq(void);
8429+extern void run_sioq(work_func_t func, struct sioq_args *args);
8430+
8431+/* Extern definitions for our privilege escalation helpers */
8432+extern void __unionfs_create(struct work_struct *work);
8433+extern void __unionfs_mkdir(struct work_struct *work);
8434+extern void __unionfs_mknod(struct work_struct *work);
8435+extern void __unionfs_symlink(struct work_struct *work);
8436+extern void __unionfs_unlink(struct work_struct *work);
8437+extern void __delete_whiteouts(struct work_struct *work);
8438+extern void __is_opaque_dir(struct work_struct *work);
8439+
8440+#endif /* not _SIOQ_H */
8441diff --git a/fs/unionfs/subr.c b/fs/unionfs/subr.c
8442new file mode 100644
8443index 0000000..8747d20
8444--- /dev/null
8445+++ b/fs/unionfs/subr.c
8446@@ -0,0 +1,95 @@
8447+/*
8448+ * Copyright (c) 2003-2008 Erez Zadok
8449+ * Copyright (c) 2003-2006 Charles P. Wright
8450+ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
8451+ * Copyright (c) 2005-2006 Junjiro Okajima
8452+ * Copyright (c) 2005 Arun M. Krishnakumar
8453+ * Copyright (c) 2004-2006 David P. Quigley
8454+ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
8455+ * Copyright (c) 2003 Puja Gupta
8456+ * Copyright (c) 2003 Harikesavan Krishnan
8457+ * Copyright (c) 2003-2008 Stony Brook University
8458+ * Copyright (c) 2003-2008 The Research Foundation of SUNY
8459+ *
8460+ * This program is free software; you can redistribute it and/or modify
8461+ * it under the terms of the GNU General Public License version 2 as
8462+ * published by the Free Software Foundation.
8463+ */
8464+
8465+#include "union.h"
8466+
8467+/*
8468+ * returns the right n_link value based on the inode type
8469+ */
8470+int unionfs_get_nlinks(const struct inode *inode)
8471+{
8472+ /* don't bother to do all the work since we're unlinked */
8473+ if (inode->i_nlink == 0)
8474+ return 0;
8475+
8476+ if (!S_ISDIR(inode->i_mode))
8477+ return unionfs_lower_inode(inode)->i_nlink;
8478+
8479+ /*
8480+ * For directories, we return 1. The only place that could cares
8481+ * about links is readdir, and there's d_type there so even that
8482+ * doesn't matter.
8483+ */
8484+ return 1;
8485+}
8486+
8487+/* copy a/m/ctime from the lower branch with the newest times */
8488+void unionfs_copy_attr_times(struct inode *upper)
8489+{
8490+ int bindex;
8491+ struct inode *lower;
8492+
8493+ if (!upper)
8494+ return;
8495+ if (ibstart(upper) < 0) {
8496+#ifdef CONFIG_UNION_FS_DEBUG
8497+ WARN_ON(ibstart(upper) < 0);
8498+#endif /* CONFIG_UNION_FS_DEBUG */
8499+ return;
8500+ }
8501+ for (bindex = ibstart(upper); bindex <= ibend(upper); bindex++) {
8502+ lower = unionfs_lower_inode_idx(upper, bindex);
8503+ if (!lower)
8504+ continue; /* not all lower dir objects may exist */
8505+ if (unlikely(timespec_compare(&upper->i_mtime,
8506+ &lower->i_mtime) < 0))
8507+ upper->i_mtime = lower->i_mtime;
8508+ if (unlikely(timespec_compare(&upper->i_ctime,
8509+ &lower->i_ctime) < 0))
8510+ upper->i_ctime = lower->i_ctime;
8511+ if (unlikely(timespec_compare(&upper->i_atime,
8512+ &lower->i_atime) < 0))
8513+ upper->i_atime = lower->i_atime;
8514+ }
8515+}
8516+
8517+/*
8518+ * A unionfs/fanout version of fsstack_copy_attr_all. Uses a
8519+ * unionfs_get_nlinks to properly calcluate the number of links to a file.
8520+ * Also, copies the max() of all a/m/ctimes for all lower inodes (which is
8521+ * important if the lower inode is a directory type)
8522+ */
8523+void unionfs_copy_attr_all(struct inode *dest,
8524+ const struct inode *src)
8525+{
8526+ dest->i_mode = src->i_mode;
8527+ dest->i_uid = src->i_uid;
8528+ dest->i_gid = src->i_gid;
8529+ dest->i_rdev = src->i_rdev;
8530+
8531+ unionfs_copy_attr_times(dest);
8532+
8533+ dest->i_blkbits = src->i_blkbits;
8534+ dest->i_flags = src->i_flags;
8535+
8536+ /*
8537+ * Update the nlinks AFTER updating the above fields, because the
8538+ * get_links callback may depend on them.
8539+ */
8540+ dest->i_nlink = unionfs_get_nlinks(dest);
8541+}
8542diff --git a/fs/unionfs/super.c b/fs/unionfs/super.c
8543new file mode 100644
8544index 0000000..e774ef3
8545--- /dev/null
8546+++ b/fs/unionfs/super.c
8547@@ -0,0 +1,1042 @@
8548+/*
8549+ * Copyright (c) 2003-2008 Erez Zadok
8550+ * Copyright (c) 2003-2006 Charles P. Wright
8551+ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
8552+ * Copyright (c) 2005-2006 Junjiro Okajima
8553+ * Copyright (c) 2005 Arun M. Krishnakumar
8554+ * Copyright (c) 2004-2006 David P. Quigley
8555+ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
8556+ * Copyright (c) 2003 Puja Gupta
8557+ * Copyright (c) 2003 Harikesavan Krishnan
8558+ * Copyright (c) 2003-2008 Stony Brook University
8559+ * Copyright (c) 2003-2008 The Research Foundation of SUNY
8560+ *
8561+ * This program is free software; you can redistribute it and/or modify
8562+ * it under the terms of the GNU General Public License version 2 as
8563+ * published by the Free Software Foundation.
8564+ */
8565+
8566+#include "union.h"
8567+
8568+/*
8569+ * The inode cache is used with alloc_inode for both our inode info and the
8570+ * vfs inode.
8571+ */
8572+static struct kmem_cache *unionfs_inode_cachep;
8573+
8574+struct inode *unionfs_iget(struct super_block *sb, unsigned long ino)
8575+{
8576+ int size;
8577+ struct unionfs_inode_info *info;
8578+ struct inode *inode;
8579+
8580+ inode = iget_locked(sb, ino);
8581+ if (!inode)
8582+ return ERR_PTR(-ENOMEM);
8583+ if (!(inode->i_state & I_NEW))
8584+ return inode;
8585+
8586+ info = UNIONFS_I(inode);
8587+ memset(info, 0, offsetof(struct unionfs_inode_info, vfs_inode));
8588+ info->bstart = -1;
8589+ info->bend = -1;
8590+ atomic_set(&info->generation,
8591+ atomic_read(&UNIONFS_SB(inode->i_sb)->generation));
8592+ spin_lock_init(&info->rdlock);
8593+ info->rdcount = 1;
8594+ info->hashsize = -1;
8595+ INIT_LIST_HEAD(&info->readdircache);
8596+
8597+ size = sbmax(inode->i_sb) * sizeof(struct inode *);
8598+ info->lower_inodes = kzalloc(size, GFP_KERNEL);
8599+ if (unlikely(!info->lower_inodes)) {
8600+ printk(KERN_CRIT "unionfs: no kernel memory when allocating "
8601+ "lower-pointer array!\n");
8602+ iget_failed(inode);
8603+ return ERR_PTR(-ENOMEM);
8604+ }
8605+
8606+ inode->i_version++;
8607+ inode->i_op = &unionfs_main_iops;
8608+ inode->i_fop = &unionfs_main_fops;
8609+
8610+ inode->i_mapping->a_ops = &unionfs_aops;
8611+
8612+ /*
8613+ * reset times so unionfs_copy_attr_all can keep out time invariants
8614+ * right (upper inode time being the max of all lower ones).
8615+ */
8616+ inode->i_atime.tv_sec = inode->i_atime.tv_nsec = 0;
8617+ inode->i_mtime.tv_sec = inode->i_mtime.tv_nsec = 0;
8618+ inode->i_ctime.tv_sec = inode->i_ctime.tv_nsec = 0;
8619+ unlock_new_inode(inode);
8620+ return inode;
8621+}
8622+
8623+/*
8624+ * we now define delete_inode, because there are two VFS paths that may
8625+ * destroy an inode: one of them calls clear inode before doing everything
8626+ * else that's needed, and the other is fine. This way we truncate the inode
8627+ * size (and its pages) and then clear our own inode, which will do an iput
8628+ * on our and the lower inode.
8629+ *
8630+ * No need to lock sb info's rwsem.
8631+ */
8632+static void unionfs_delete_inode(struct inode *inode)
8633+{
8634+#if BITS_PER_LONG == 32 && defined(CONFIG_SMP)
8635+ spin_lock(&inode->i_lock);
8636+#endif
8637+ i_size_write(inode, 0); /* every f/s seems to do that */
8638+#if BITS_PER_LONG == 32 && defined(CONFIG_SMP)
8639+ spin_unlock(&inode->i_lock);
8640+#endif
8641+
8642+ if (inode->i_data.nrpages)
8643+ truncate_inode_pages(&inode->i_data, 0);
8644+
8645+ clear_inode(inode);
8646+}
8647+
8648+/*
8649+ * final actions when unmounting a file system
8650+ *
8651+ * No need to lock rwsem.
8652+ */
8653+static void unionfs_put_super(struct super_block *sb)
8654+{
8655+ int bindex, bstart, bend;
8656+ struct unionfs_sb_info *spd;
8657+ int leaks = 0;
8658+
8659+ spd = UNIONFS_SB(sb);
8660+ if (!spd)
8661+ return;
8662+
8663+ bstart = sbstart(sb);
8664+ bend = sbend(sb);
8665+
8666+ /* Make sure we have no leaks of branchget/branchput. */
8667+ for (bindex = bstart; bindex <= bend; bindex++)
8668+ if (unlikely(branch_count(sb, bindex) != 0)) {
8669+ printk(KERN_CRIT
8670+ "unionfs: branch %d has %d references left!\n",
8671+ bindex, branch_count(sb, bindex));
8672+ leaks = 1;
8673+ }
8674+ BUG_ON(leaks != 0);
8675+
8676+ /* decrement lower super references */
8677+ for (bindex = bstart; bindex <= bend; bindex++) {
8678+ struct super_block *s;
8679+ s = unionfs_lower_super_idx(sb, bindex);
8680+ unionfs_set_lower_super_idx(sb, bindex, NULL);
8681+ atomic_dec(&s->s_active);
8682+ }
8683+
8684+ kfree(spd->dev_name);
8685+ kfree(spd->data);
8686+ kfree(spd);
8687+ sb->s_fs_info = NULL;
8688+}
8689+
8690+/*
8691+ * Since people use this to answer the "How big of a file can I write?"
8692+ * question, we report the size of the highest priority branch as the size of
8693+ * the union.
8694+ */
8695+static int unionfs_statfs(struct dentry *dentry, struct kstatfs *buf)
8696+{
8697+ int err = 0;
8698+ struct super_block *sb;
8699+ struct dentry *lower_dentry;
8700+
8701+ sb = dentry->d_sb;
8702+
8703+ unionfs_read_lock(sb, UNIONFS_SMUTEX_CHILD);
8704+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
8705+
8706+ if (unlikely(!__unionfs_d_revalidate_chain(dentry, NULL, false))) {
8707+ err = -ESTALE;
8708+ goto out;
8709+ }
8710+ unionfs_check_dentry(dentry);
8711+
8712+ lower_dentry = unionfs_lower_dentry(sb->s_root);
8713+ err = vfs_statfs(lower_dentry, buf);
8714+
8715+ /* set return buf to our f/s to avoid confusing user-level utils */
8716+ buf->f_type = UNIONFS_SUPER_MAGIC;
8717+ /*
8718+ * Our maximum file name can is shorter by a few bytes because every
8719+ * file name could potentially be whited-out.
8720+ *
8721+ * XXX: this restriction goes away with ODF.
8722+ */
8723+ unionfs_set_max_namelen(&buf->f_namelen);
8724+
8725+ /*
8726+ * reset two fields to avoid confusing user-land.
8727+ * XXX: is this still necessary?
8728+ */
8729+ memset(&buf->f_fsid, 0, sizeof(__kernel_fsid_t));
8730+ memset(&buf->f_spare, 0, sizeof(buf->f_spare));
8731+
8732+out:
8733+ unionfs_check_dentry(dentry);
8734+ unionfs_unlock_dentry(dentry);
8735+ unionfs_read_unlock(sb);
8736+ return err;
8737+}
8738+
8739+/* handle mode changing during remount */
8740+static noinline_for_stack int do_remount_mode_option(
8741+ char *optarg,
8742+ int cur_branches,
8743+ struct unionfs_data *new_data,
8744+ struct path *new_lower_paths)
8745+{
8746+ int err = -EINVAL;
8747+ int perms, idx;
8748+ char *modename = strchr(optarg, '=');
8749+ struct nameidata nd;
8750+
8751+ /* by now, optarg contains the branch name */
8752+ if (!*optarg) {
8753+ printk(KERN_ERR
8754+ "unionfs: no branch specified for mode change\n");
8755+ goto out;
8756+ }
8757+ if (!modename) {
8758+ printk(KERN_ERR "unionfs: branch \"%s\" requires a mode\n",
8759+ optarg);
8760+ goto out;
8761+ }
8762+ *modename++ = '\0';
8763+ err = parse_branch_mode(modename, &perms);
8764+ if (err) {
8765+ printk(KERN_ERR "unionfs: invalid mode \"%s\" for \"%s\"\n",
8766+ modename, optarg);
8767+ goto out;
8768+ }
8769+
8770+ /*
8771+ * Find matching branch index. For now, this assumes that nothing
8772+ * has been mounted on top of this Unionfs stack. Once we have /odf
8773+ * and cache-coherency resolved, we'll address the branch-path
8774+ * uniqueness.
8775+ */
8776+ err = path_lookup(optarg, LOOKUP_FOLLOW, &nd);
8777+ if (err) {
8778+ printk(KERN_ERR "unionfs: error accessing "
8779+ "lower directory \"%s\" (error %d)\n",
8780+ optarg, err);
8781+ goto out;
8782+ }
8783+ for (idx = 0; idx < cur_branches; idx++)
8784+ if (nd.path.mnt == new_lower_paths[idx].mnt &&
8785+ nd.path.dentry == new_lower_paths[idx].dentry)
8786+ break;
8787+ path_put(&nd.path); /* no longer needed */
8788+ if (idx == cur_branches) {
8789+ err = -ENOENT; /* err may have been reset above */
8790+ printk(KERN_ERR "unionfs: branch \"%s\" "
8791+ "not found\n", optarg);
8792+ goto out;
8793+ }
8794+ /* check/change mode for existing branch */
8795+ /* we don't warn if perms==branchperms */
8796+ new_data[idx].branchperms = perms;
8797+ err = 0;
8798+out:
8799+ return err;
8800+}
8801+
8802+/* handle branch deletion during remount */
8803+static noinline_for_stack int do_remount_del_option(
8804+ char *optarg, int cur_branches,
8805+ struct unionfs_data *new_data,
8806+ struct path *new_lower_paths)
8807+{
8808+ int err = -EINVAL;
8809+ int idx;
8810+ struct nameidata nd;
8811+
8812+ /* optarg contains the branch name to delete */
8813+
8814+ /*
8815+ * Find matching branch index. For now, this assumes that nothing
8816+ * has been mounted on top of this Unionfs stack. Once we have /odf
8817+ * and cache-coherency resolved, we'll address the branch-path
8818+ * uniqueness.
8819+ */
8820+ err = path_lookup(optarg, LOOKUP_FOLLOW, &nd);
8821+ if (err) {
8822+ printk(KERN_ERR "unionfs: error accessing "
8823+ "lower directory \"%s\" (error %d)\n",
8824+ optarg, err);
8825+ goto out;
8826+ }
8827+ for (idx = 0; idx < cur_branches; idx++)
8828+ if (nd.path.mnt == new_lower_paths[idx].mnt &&
8829+ nd.path.dentry == new_lower_paths[idx].dentry)
8830+ break;
8831+ path_put(&nd.path); /* no longer needed */
8832+ if (idx == cur_branches) {
8833+ printk(KERN_ERR "unionfs: branch \"%s\" "
8834+ "not found\n", optarg);
8835+ err = -ENOENT;
8836+ goto out;
8837+ }
8838+ /* check if there are any open files on the branch to be deleted */
8839+ if (atomic_read(&new_data[idx].open_files) > 0) {
8840+ err = -EBUSY;
8841+ goto out;
8842+ }
8843+
8844+ /*
8845+ * Now we have to delete the branch. First, release any handles it
8846+ * has. Then, move the remaining array indexes past "idx" in
8847+ * new_data and new_lower_paths one to the left. Finally, adjust
8848+ * cur_branches.
8849+ */
8850+ path_put(&new_lower_paths[idx]);
8851+
8852+ if (idx < cur_branches - 1) {
8853+ /* if idx==cur_branches-1, we delete last branch: easy */
8854+ memmove(&new_data[idx], &new_data[idx+1],
8855+ (cur_branches - 1 - idx) *
8856+ sizeof(struct unionfs_data));
8857+ memmove(&new_lower_paths[idx], &new_lower_paths[idx+1],
8858+ (cur_branches - 1 - idx) * sizeof(struct path));
8859+ }
8860+
8861+ err = 0;
8862+out:
8863+ return err;
8864+}
8865+
8866+/* handle branch insertion during remount */
8867+static noinline_for_stack int do_remount_add_option(
8868+ char *optarg, int cur_branches,
8869+ struct unionfs_data *new_data,
8870+ struct path *new_lower_paths,
8871+ int *high_branch_id)
8872+{
8873+ int err = -EINVAL;
8874+ int perms;
8875+ int idx = 0; /* default: insert at beginning */
8876+ char *new_branch , *modename = NULL;
8877+ struct nameidata nd;
8878+
8879+ /*
8880+ * optarg can be of several forms:
8881+ *
8882+ * /bar:/foo insert /foo before /bar
8883+ * /bar:/foo=ro insert /foo in ro mode before /bar
8884+ * /foo insert /foo in the beginning (prepend)
8885+ * :/foo insert /foo at the end (append)
8886+ */
8887+ if (*optarg == ':') { /* append? */
8888+ new_branch = optarg + 1; /* skip ':' */
8889+ idx = cur_branches;
8890+ goto found_insertion_point;
8891+ }
8892+ new_branch = strchr(optarg, ':');
8893+ if (!new_branch) { /* prepend? */
8894+ new_branch = optarg;
8895+ goto found_insertion_point;
8896+ }
8897+ *new_branch++ = '\0'; /* holds path+mode of new branch */
8898+
8899+ /*
8900+ * Find matching branch index. For now, this assumes that nothing
8901+ * has been mounted on top of this Unionfs stack. Once we have /odf
8902+ * and cache-coherency resolved, we'll address the branch-path
8903+ * uniqueness.
8904+ */
8905+ err = path_lookup(optarg, LOOKUP_FOLLOW, &nd);
8906+ if (err) {
8907+ printk(KERN_ERR "unionfs: error accessing "
8908+ "lower directory \"%s\" (error %d)\n",
8909+ optarg, err);
8910+ goto out;
8911+ }
8912+ for (idx = 0; idx < cur_branches; idx++)
8913+ if (nd.path.mnt == new_lower_paths[idx].mnt &&
8914+ nd.path.dentry == new_lower_paths[idx].dentry)
8915+ break;
8916+ path_put(&nd.path); /* no longer needed */
8917+ if (idx == cur_branches) {
8918+ printk(KERN_ERR "unionfs: branch \"%s\" "
8919+ "not found\n", optarg);
8920+ err = -ENOENT;
8921+ goto out;
8922+ }
8923+
8924+ /*
8925+ * At this point idx will hold the index where the new branch should
8926+ * be inserted before.
8927+ */
8928+found_insertion_point:
8929+ /* find the mode for the new branch */
8930+ if (new_branch)
8931+ modename = strchr(new_branch, '=');
8932+ if (modename)
8933+ *modename++ = '\0';
8934+ if (!new_branch || !*new_branch) {
8935+ printk(KERN_ERR "unionfs: null new branch\n");
8936+ err = -EINVAL;
8937+ goto out;
8938+ }
8939+ err = parse_branch_mode(modename, &perms);
8940+ if (err) {
8941+ printk(KERN_ERR "unionfs: invalid mode \"%s\" for "
8942+ "branch \"%s\"\n", modename, new_branch);
8943+ goto out;
8944+ }
8945+ err = path_lookup(new_branch, LOOKUP_FOLLOW, &nd);
8946+ if (err) {
8947+ printk(KERN_ERR "unionfs: error accessing "
8948+ "lower directory \"%s\" (error %d)\n",
8949+ new_branch, err);
8950+ goto out;
8951+ }
8952+ /*
8953+ * It's probably safe to check_mode the new branch to insert. Note:
8954+ * we don't allow inserting branches which are unionfs's by
8955+ * themselves (check_branch returns EINVAL in that case). This is
8956+ * because this code base doesn't support stacking unionfs: the ODF
8957+ * code base supports that correctly.
8958+ */
8959+ err = check_branch(&nd);
8960+ if (err) {
8961+ printk(KERN_ERR "unionfs: lower directory "
8962+ "\"%s\" is not a valid branch\n", optarg);
8963+ path_put(&nd.path);
8964+ goto out;
8965+ }
8966+
8967+ /*
8968+ * Now we have to insert the new branch. But first, move the bits
8969+ * to make space for the new branch, if needed. Finally, adjust
8970+ * cur_branches.
8971+ * We don't release nd here; it's kept until umount/remount.
8972+ */
8973+ if (idx < cur_branches) {
8974+ /* if idx==cur_branches, we append: easy */
8975+ memmove(&new_data[idx+1], &new_data[idx],
8976+ (cur_branches - idx) * sizeof(struct unionfs_data));
8977+ memmove(&new_lower_paths[idx+1], &new_lower_paths[idx],
8978+ (cur_branches - idx) * sizeof(struct path));
8979+ }
8980+ new_lower_paths[idx].dentry = nd.path.dentry;
8981+ new_lower_paths[idx].mnt = nd.path.mnt;
8982+
8983+ new_data[idx].sb = nd.path.dentry->d_sb;
8984+ atomic_set(&new_data[idx].open_files, 0);
8985+ new_data[idx].branchperms = perms;
8986+ new_data[idx].branch_id = ++*high_branch_id; /* assign new branch ID */
8987+
8988+ err = 0;
8989+out:
8990+ return err;
8991+}
8992+
8993+
8994+/*
8995+ * Support branch management options on remount.
8996+ *
8997+ * See Documentation/filesystems/unionfs/ for details.
8998+ *
8999+ * @flags: numeric mount options
9000+ * @options: mount options string
9001+ *
9002+ * This function can rearrange a mounted union dynamically, adding and
9003+ * removing branches, including changing branch modes. Clearly this has to
9004+ * be done safely and atomically. Luckily, the VFS already calls this
9005+ * function with lock_super(sb) and lock_kernel() held, preventing
9006+ * concurrent mixing of new mounts, remounts, and unmounts. Moreover,
9007+ * do_remount_sb(), our caller function, already called shrink_dcache_sb(sb)
9008+ * to purge dentries/inodes from our superblock, and also called
9009+ * fsync_super(sb) to purge any dirty pages. So we're good.
9010+ *
9011+ * XXX: however, our remount code may also need to invalidate mapped pages
9012+ * so as to force them to be re-gotten from the (newly reconfigured) lower
9013+ * branches. This has to wait for proper mmap and cache coherency support
9014+ * in the VFS.
9015+ *
9016+ */
9017+static int unionfs_remount_fs(struct super_block *sb, int *flags,
9018+ char *options)
9019+{
9020+ int err = 0;
9021+ int i;
9022+ char *optionstmp, *tmp_to_free; /* kstrdup'ed of "options" */
9023+ char *optname;
9024+ int cur_branches = 0; /* no. of current branches */
9025+ int new_branches = 0; /* no. of branches actually left in the end */
9026+ int add_branches; /* est. no. of branches to add */
9027+ int del_branches; /* est. no. of branches to del */
9028+ int max_branches; /* max possible no. of branches */
9029+ struct unionfs_data *new_data = NULL, *tmp_data = NULL;
9030+ struct path *new_lower_paths = NULL, *tmp_lower_paths = NULL;
9031+ struct inode **new_lower_inodes = NULL;
9032+ int new_high_branch_id; /* new high branch ID */
9033+ int size; /* memory allocation size, temp var */
9034+ int old_ibstart, old_ibend;
9035+
9036+ unionfs_write_lock(sb);
9037+
9038+ /*
9039+ * The VFS will take care of "ro" and "rw" flags, and we can safely
9040+ * ignore MS_SILENT, but anything else left over is an error. So we
9041+ * need to check if any other flags may have been passed (none are
9042+ * allowed/supported as of now).
9043+ */
9044+ if ((*flags & ~(MS_RDONLY | MS_SILENT)) != 0) {
9045+ printk(KERN_ERR
9046+ "unionfs: remount flags 0x%x unsupported\n", *flags);
9047+ err = -EINVAL;
9048+ goto out_error;
9049+ }
9050+
9051+ /*
9052+ * If 'options' is NULL, it's probably because the user just changed
9053+ * the union to a "ro" or "rw" and the VFS took care of it. So
9054+ * nothing to do and we're done.
9055+ */
9056+ if (!options || options[0] == '\0')
9057+ goto out_error;
9058+
9059+ /*
9060+ * Find out how many branches we will have in the end, counting
9061+ * "add" and "del" commands. Copy the "options" string because
9062+ * strsep modifies the string and we need it later.
9063+ */
9064+ tmp_to_free = kstrdup(options, GFP_KERNEL);
9065+ optionstmp = tmp_to_free;
9066+ if (unlikely(!optionstmp)) {
9067+ err = -ENOMEM;
9068+ goto out_free;
9069+ }
9070+ cur_branches = sbmax(sb); /* current no. branches */
9071+ new_branches = sbmax(sb);
9072+ del_branches = 0;
9073+ add_branches = 0;
9074+ new_high_branch_id = sbhbid(sb); /* save current high_branch_id */
9075+ while ((optname = strsep(&optionstmp, ",")) != NULL) {
9076+ char *optarg;
9077+
9078+ if (!optname || !*optname)
9079+ continue;
9080+
9081+ optarg = strchr(optname, '=');
9082+ if (optarg)
9083+ *optarg++ = '\0';
9084+
9085+ if (!strcmp("add", optname))
9086+ add_branches++;
9087+ else if (!strcmp("del", optname))
9088+ del_branches++;
9089+ }
9090+ kfree(tmp_to_free);
9091+ /* after all changes, will we have at least one branch left? */
9092+ if ((new_branches + add_branches - del_branches) < 1) {
9093+ printk(KERN_ERR
9094+ "unionfs: no branches left after remount\n");
9095+ err = -EINVAL;
9096+ goto out_free;
9097+ }
9098+
9099+ /*
9100+ * Since we haven't actually parsed all the add/del options, nor
9101+ * have we checked them for errors, we don't know for sure how many
9102+ * branches we will have after all changes have taken place. In
9103+ * fact, the total number of branches left could be less than what
9104+ * we have now. So we need to allocate space for a temporary
9105+ * placeholder that is at least as large as the maximum number of
9106+ * branches we *could* have, which is the current number plus all
9107+ * the additions. Once we're done with these temp placeholders, we
9108+ * may have to re-allocate the final size, copy over from the temp,
9109+ * and then free the temps (done near the end of this function).
9110+ */
9111+ max_branches = cur_branches + add_branches;
9112+ /* allocate space for new pointers to lower dentry */
9113+ tmp_data = kcalloc(max_branches,
9114+ sizeof(struct unionfs_data), GFP_KERNEL);
9115+ if (unlikely(!tmp_data)) {
9116+ err = -ENOMEM;
9117+ goto out_free;
9118+ }
9119+ /* allocate space for new pointers to lower paths */
9120+ tmp_lower_paths = kcalloc(max_branches,
9121+ sizeof(struct path), GFP_KERNEL);
9122+ if (unlikely(!tmp_lower_paths)) {
9123+ err = -ENOMEM;
9124+ goto out_free;
9125+ }
9126+ /* copy current info into new placeholders, incrementing refcnts */
9127+ memcpy(tmp_data, UNIONFS_SB(sb)->data,
9128+ cur_branches * sizeof(struct unionfs_data));
9129+ memcpy(tmp_lower_paths, UNIONFS_D(sb->s_root)->lower_paths,
9130+ cur_branches * sizeof(struct path));
9131+ for (i = 0; i < cur_branches; i++)
9132+ path_get(&tmp_lower_paths[i]); /* drop refs at end of fxn */
9133+
9134+ /*******************************************************************
9135+ * For each branch command, do path_lookup on the requested branch,
9136+ * and apply the change to a temp branch list. To handle errors, we
9137+ * already dup'ed the old arrays (above), and increased the refcnts
9138+ * on various f/s objects. So now we can do all the path_lookups
9139+ * and branch-management commands on the new arrays. If it fail mid
9140+ * way, we free the tmp arrays and *put all objects. If we succeed,
9141+ * then we free old arrays and *put its objects, and then replace
9142+ * the arrays with the new tmp list (we may have to re-allocate the
9143+ * memory because the temp lists could have been larger than what we
9144+ * actually needed).
9145+ *******************************************************************/
9146+
9147+ while ((optname = strsep(&options, ",")) != NULL) {
9148+ char *optarg;
9149+
9150+ if (!optname || !*optname)
9151+ continue;
9152+ /*
9153+ * At this stage optname holds a comma-delimited option, but
9154+ * without the commas. Next, we need to break the string on
9155+ * the '=' symbol to separate CMD=ARG, where ARG itself can
9156+ * be KEY=VAL. For example, in mode=/foo=rw, CMD is "mode",
9157+ * KEY is "/foo", and VAL is "rw".
9158+ */
9159+ optarg = strchr(optname, '=');
9160+ if (optarg)
9161+ *optarg++ = '\0';
9162+ /* incgen remount option (instead of old ioctl) */
9163+ if (!strcmp("incgen", optname)) {
9164+ err = 0;
9165+ goto out_no_change;
9166+ }
9167+
9168+ /*
9169+ * All of our options take an argument now. (Insert ones
9170+ * that don't above this check.) So at this stage optname
9171+ * contains the CMD part and optarg contains the ARG part.
9172+ */
9173+ if (!optarg || !*optarg) {
9174+ printk(KERN_ERR "unionfs: all remount options require "
9175+ "an argument (%s)\n", optname);
9176+ err = -EINVAL;
9177+ goto out_release;
9178+ }
9179+
9180+ if (!strcmp("add", optname)) {
9181+ err = do_remount_add_option(optarg, new_branches,
9182+ tmp_data,
9183+ tmp_lower_paths,
9184+ &new_high_branch_id);
9185+ if (err)
9186+ goto out_release;
9187+ new_branches++;
9188+ if (new_branches > UNIONFS_MAX_BRANCHES) {
9189+ printk(KERN_ERR "unionfs: command exceeds "
9190+ "%d branches\n", UNIONFS_MAX_BRANCHES);
9191+ err = -E2BIG;
9192+ goto out_release;
9193+ }
9194+ continue;
9195+ }
9196+ if (!strcmp("del", optname)) {
9197+ err = do_remount_del_option(optarg, new_branches,
9198+ tmp_data,
9199+ tmp_lower_paths);
9200+ if (err)
9201+ goto out_release;
9202+ new_branches--;
9203+ continue;
9204+ }
9205+ if (!strcmp("mode", optname)) {
9206+ err = do_remount_mode_option(optarg, new_branches,
9207+ tmp_data,
9208+ tmp_lower_paths);
9209+ if (err)
9210+ goto out_release;
9211+ continue;
9212+ }
9213+
9214+ /*
9215+ * When you use "mount -o remount,ro", mount(8) will
9216+ * reportedly pass the original dirs= string from
9217+ * /proc/mounts. So for now, we have to ignore dirs= and
9218+ * not consider it an error, unless we want to allow users
9219+ * to pass dirs= in remount. Note that to allow the VFS to
9220+ * actually process the ro/rw remount options, we have to
9221+ * return 0 from this function.
9222+ */
9223+ if (!strcmp("dirs", optname)) {
9224+ printk(KERN_WARNING
9225+ "unionfs: remount ignoring option \"%s\"\n",
9226+ optname);
9227+ continue;
9228+ }
9229+
9230+ err = -EINVAL;
9231+ printk(KERN_ERR
9232+ "unionfs: unrecognized option \"%s\"\n", optname);
9233+ goto out_release;
9234+ }
9235+
9236+out_no_change:
9237+
9238+ /******************************************************************
9239+ * WE'RE ALMOST DONE: check if leftmost branch might be read-only,
9240+ * see if we need to allocate a small-sized new vector, copy the
9241+ * vectors to their correct place, release the refcnt of the older
9242+ * ones, and return. Also handle invalidating any pages that will
9243+ * have to be re-read.
9244+ *******************************************************************/
9245+
9246+ if (!(tmp_data[0].branchperms & MAY_WRITE)) {
9247+ printk(KERN_ERR "unionfs: leftmost branch cannot be read-only "
9248+ "(use \"remount,ro\" to create a read-only union)\n");
9249+ err = -EINVAL;
9250+ goto out_release;
9251+ }
9252+
9253+ /* (re)allocate space for new pointers to lower dentry */
9254+ size = new_branches * sizeof(struct unionfs_data);
9255+ new_data = krealloc(tmp_data, size, GFP_KERNEL);
9256+ if (unlikely(!new_data)) {
9257+ err = -ENOMEM;
9258+ goto out_release;
9259+ }
9260+
9261+ /* allocate space for new pointers to lower paths */
9262+ size = new_branches * sizeof(struct path);
9263+ new_lower_paths = krealloc(tmp_lower_paths, size, GFP_KERNEL);
9264+ if (unlikely(!new_lower_paths)) {
9265+ err = -ENOMEM;
9266+ goto out_release;
9267+ }
9268+
9269+ /* allocate space for new pointers to lower inodes */
9270+ new_lower_inodes = kcalloc(new_branches,
9271+ sizeof(struct inode *), GFP_KERNEL);
9272+ if (unlikely(!new_lower_inodes)) {
9273+ err = -ENOMEM;
9274+ goto out_release;
9275+ }
9276+
9277+ /*
9278+ * OK, just before we actually put the new set of branches in place,
9279+ * we need to ensure that our own f/s has no dirty objects left.
9280+ * Luckily, do_remount_sb() already calls shrink_dcache_sb(sb) and
9281+ * fsync_super(sb), taking care of dentries, inodes, and dirty
9282+ * pages. So all that's left is for us to invalidate any leftover
9283+ * (non-dirty) pages to ensure that they will be re-read from the
9284+ * new lower branches (and to support mmap).
9285+ */
9286+
9287+ /*
9288+ * Once we finish the remounting successfully, our superblock
9289+ * generation number will have increased. This will be detected by
9290+ * our dentry-revalidation code upon subsequent f/s operations
9291+ * through unionfs. The revalidation code will rebuild the union of
9292+ * lower inodes for a given unionfs inode and invalidate any pages
9293+ * of such "stale" inodes (by calling our purge_inode_data
9294+ * function). This revalidation will happen lazily and
9295+ * incrementally, as users perform operations on cached inodes. We
9296+ * would like to encourage this revalidation to happen sooner if
9297+ * possible, so we like to try to invalidate as many other pages in
9298+ * our superblock as we can. We used to call drop_pagecache_sb() or
9299+ * a variant thereof, but either method was racy (drop_caches alone
9300+ * is known to be racy). So now we let the revalidation happen on a
9301+ * per file basis in ->d_revalidate.
9302+ */
9303+
9304+ /* grab new lower super references; release old ones */
9305+ for (i = 0; i < new_branches; i++)
9306+ atomic_inc(&new_data[i].sb->s_active);
9307+ for (i = 0; i < sbmax(sb); i++)
9308+ atomic_dec(&UNIONFS_SB(sb)->data[i].sb->s_active);
9309+
9310+ /* copy new vectors into their correct place */
9311+ tmp_data = UNIONFS_SB(sb)->data;
9312+ UNIONFS_SB(sb)->data = new_data;
9313+ new_data = NULL; /* so don't free good pointers below */
9314+ tmp_lower_paths = UNIONFS_D(sb->s_root)->lower_paths;
9315+ UNIONFS_D(sb->s_root)->lower_paths = new_lower_paths;
9316+ new_lower_paths = NULL; /* so don't free good pointers below */
9317+
9318+ /* update our unionfs_sb_info and root dentry index of last branch */
9319+ i = sbmax(sb); /* save no. of branches to release at end */
9320+ sbend(sb) = new_branches - 1;
9321+ dbend(sb->s_root) = new_branches - 1;
9322+ old_ibstart = ibstart(sb->s_root->d_inode);
9323+ old_ibend = ibend(sb->s_root->d_inode);
9324+ ibend(sb->s_root->d_inode) = new_branches - 1;
9325+ UNIONFS_D(sb->s_root)->bcount = new_branches;
9326+ new_branches = i; /* no. of branches to release below */
9327+
9328+ /*
9329+ * Update lower inodes: 3 steps
9330+ * 1. grab ref on all new lower inodes
9331+ */
9332+ for (i = dbstart(sb->s_root); i <= dbend(sb->s_root); i++) {
9333+ struct dentry *lower_dentry =
9334+ unionfs_lower_dentry_idx(sb->s_root, i);
9335+ igrab(lower_dentry->d_inode);
9336+ new_lower_inodes[i] = lower_dentry->d_inode;
9337+ }
9338+ /* 2. release reference on all older lower inodes */
9339+ iput_lowers(sb->s_root->d_inode, old_ibstart, old_ibend, true);
9340+ /* 3. update root dentry's inode to new lower_inodes array */
9341+ UNIONFS_I(sb->s_root->d_inode)->lower_inodes = new_lower_inodes;
9342+ new_lower_inodes = NULL;
9343+
9344+ /* maxbytes may have changed */
9345+ sb->s_maxbytes = unionfs_lower_super_idx(sb, 0)->s_maxbytes;
9346+ /* update high branch ID */
9347+ sbhbid(sb) = new_high_branch_id;
9348+
9349+ /* update our sb->generation for revalidating objects */
9350+ i = atomic_inc_return(&UNIONFS_SB(sb)->generation);
9351+ atomic_set(&UNIONFS_D(sb->s_root)->generation, i);
9352+ atomic_set(&UNIONFS_I(sb->s_root->d_inode)->generation, i);
9353+ if (!(*flags & MS_SILENT))
9354+ pr_info("unionfs: %s: new generation number %d\n",
9355+ UNIONFS_SB(sb)->dev_name, i);
9356+ /* finally, update the root dentry's times */
9357+ unionfs_copy_attr_times(sb->s_root->d_inode);
9358+ err = 0; /* reset to success */
9359+
9360+ /*
9361+ * The code above falls through to the next label, and releases the
9362+ * refcnts of the older ones (stored in tmp_*): if we fell through
9363+ * here, it means success. However, if we jump directly to this
9364+ * label from any error above, then an error occurred after we
9365+ * grabbed various refcnts, and so we have to release the
9366+ * temporarily constructed structures.
9367+ */
9368+out_release:
9369+ /* no need to cleanup/release anything in tmp_data */
9370+ if (tmp_lower_paths)
9371+ for (i = 0; i < new_branches; i++)
9372+ path_put(&tmp_lower_paths[i]);
9373+out_free:
9374+ kfree(tmp_lower_paths);
9375+ kfree(tmp_data);
9376+ kfree(new_lower_paths);
9377+ kfree(new_data);
9378+ kfree(new_lower_inodes);
9379+out_error:
9380+ unionfs_check_dentry(sb->s_root);
9381+ unionfs_write_unlock(sb);
9382+ return err;
9383+}
9384+
9385+/*
9386+ * Called by iput() when the inode reference count reached zero
9387+ * and the inode is not hashed anywhere. Used to clear anything
9388+ * that needs to be, before the inode is completely destroyed and put
9389+ * on the inode free list.
9390+ *
9391+ * No need to lock sb info's rwsem.
9392+ */
9393+static void unionfs_clear_inode(struct inode *inode)
9394+{
9395+ int bindex, bstart, bend;
9396+ struct inode *lower_inode;
9397+ struct list_head *pos, *n;
9398+ struct unionfs_dir_state *rdstate;
9399+
9400+ list_for_each_safe(pos, n, &UNIONFS_I(inode)->readdircache) {
9401+ rdstate = list_entry(pos, struct unionfs_dir_state, cache);
9402+ list_del(&rdstate->cache);
9403+ free_rdstate(rdstate);
9404+ }
9405+
9406+ /*
9407+ * Decrement a reference to a lower_inode, which was incremented
9408+ * by our read_inode when it was created initially.
9409+ */
9410+ bstart = ibstart(inode);
9411+ bend = ibend(inode);
9412+ if (bstart >= 0) {
9413+ for (bindex = bstart; bindex <= bend; bindex++) {
9414+ lower_inode = unionfs_lower_inode_idx(inode, bindex);
9415+ if (!lower_inode)
9416+ continue;
9417+ unionfs_set_lower_inode_idx(inode, bindex, NULL);
9418+ /* see Documentation/filesystems/unionfs/issues.txt */
9419+ lockdep_off();
9420+ iput(lower_inode);
9421+ lockdep_on();
9422+ }
9423+ }
9424+
9425+ kfree(UNIONFS_I(inode)->lower_inodes);
9426+ UNIONFS_I(inode)->lower_inodes = NULL;
9427+}
9428+
9429+static struct inode *unionfs_alloc_inode(struct super_block *sb)
9430+{
9431+ struct unionfs_inode_info *i;
9432+
9433+ i = kmem_cache_alloc(unionfs_inode_cachep, GFP_KERNEL);
9434+ if (unlikely(!i))
9435+ return NULL;
9436+
9437+ /* memset everything up to the inode to 0 */
9438+ memset(i, 0, offsetof(struct unionfs_inode_info, vfs_inode));
9439+
9440+ i->vfs_inode.i_version = 1;
9441+ return &i->vfs_inode;
9442+}
9443+
9444+static void unionfs_destroy_inode(struct inode *inode)
9445+{
9446+ kmem_cache_free(unionfs_inode_cachep, UNIONFS_I(inode));
9447+}
9448+
9449+/* unionfs inode cache constructor */
9450+static void init_once(void *obj)
9451+{
9452+ struct unionfs_inode_info *i = obj;
9453+
9454+ inode_init_once(&i->vfs_inode);
9455+}
9456+
9457+int unionfs_init_inode_cache(void)
9458+{
9459+ int err = 0;
9460+
9461+ unionfs_inode_cachep =
9462+ kmem_cache_create("unionfs_inode_cache",
9463+ sizeof(struct unionfs_inode_info), 0,
9464+ SLAB_RECLAIM_ACCOUNT, init_once);
9465+ if (unlikely(!unionfs_inode_cachep))
9466+ err = -ENOMEM;
9467+ return err;
9468+}
9469+
9470+/* unionfs inode cache destructor */
9471+void unionfs_destroy_inode_cache(void)
9472+{
9473+ if (unionfs_inode_cachep)
9474+ kmem_cache_destroy(unionfs_inode_cachep);
9475+}
9476+
9477+/*
9478+ * Called when we have a dirty inode, right here we only throw out
9479+ * parts of our readdir list that are too old.
9480+ *
9481+ * No need to grab sb info's rwsem.
9482+ */
9483+static int unionfs_write_inode(struct inode *inode, int sync)
9484+{
9485+ struct list_head *pos, *n;
9486+ struct unionfs_dir_state *rdstate;
9487+
9488+ spin_lock(&UNIONFS_I(inode)->rdlock);
9489+ list_for_each_safe(pos, n, &UNIONFS_I(inode)->readdircache) {
9490+ rdstate = list_entry(pos, struct unionfs_dir_state, cache);
9491+ /* We keep this list in LRU order. */
9492+ if ((rdstate->access + RDCACHE_JIFFIES) > jiffies)
9493+ break;
9494+ UNIONFS_I(inode)->rdcount--;
9495+ list_del(&rdstate->cache);
9496+ free_rdstate(rdstate);
9497+ }
9498+ spin_unlock(&UNIONFS_I(inode)->rdlock);
9499+
9500+ return 0;
9501+}
9502+
9503+/*
9504+ * Used only in nfs, to kill any pending RPC tasks, so that subsequent
9505+ * code can actually succeed and won't leave tasks that need handling.
9506+ */
9507+static void unionfs_umount_begin(struct super_block *sb)
9508+{
9509+ struct super_block *lower_sb;
9510+ int bindex, bstart, bend;
9511+
9512+ unionfs_read_lock(sb, UNIONFS_SMUTEX_CHILD);
9513+
9514+ bstart = sbstart(sb);
9515+ bend = sbend(sb);
9516+ for (bindex = bstart; bindex <= bend; bindex++) {
9517+ lower_sb = unionfs_lower_super_idx(sb, bindex);
9518+
9519+ if (lower_sb && lower_sb->s_op &&
9520+ lower_sb->s_op->umount_begin)
9521+ lower_sb->s_op->umount_begin(lower_sb);
9522+ }
9523+
9524+ unionfs_read_unlock(sb);
9525+}
9526+
9527+static int unionfs_show_options(struct seq_file *m, struct vfsmount *mnt)
9528+{
9529+ struct super_block *sb = mnt->mnt_sb;
9530+ int ret = 0;
9531+ char *tmp_page;
9532+ char *path;
9533+ int bindex, bstart, bend;
9534+ int perms;
9535+
9536+ unionfs_read_lock(sb, UNIONFS_SMUTEX_CHILD);
9537+
9538+ unionfs_lock_dentry(sb->s_root, UNIONFS_DMUTEX_CHILD);
9539+
9540+ tmp_page = (char *) __get_free_page(GFP_KERNEL);
9541+ if (unlikely(!tmp_page)) {
9542+ ret = -ENOMEM;
9543+ goto out;
9544+ }
9545+
9546+ bstart = sbstart(sb);
9547+ bend = sbend(sb);
9548+
9549+ seq_printf(m, ",dirs=");
9550+ for (bindex = bstart; bindex <= bend; bindex++) {
9551+ struct path p;
9552+ p.dentry = unionfs_lower_dentry_idx(sb->s_root, bindex);
9553+ p.mnt = unionfs_lower_mnt_idx(sb->s_root, bindex);
9554+ path = d_path(&p, tmp_page, PAGE_SIZE);
9555+ if (IS_ERR(path)) {
9556+ ret = PTR_ERR(path);
9557+ goto out;
9558+ }
9559+
9560+ perms = branchperms(sb, bindex);
9561+
9562+ seq_printf(m, "%s=%s", path,
9563+ perms & MAY_WRITE ? "rw" : "ro");
9564+ if (bindex != bend)
9565+ seq_printf(m, ":");
9566+ }
9567+
9568+out:
9569+ free_page((unsigned long) tmp_page);
9570+
9571+ unionfs_unlock_dentry(sb->s_root);
9572+
9573+ unionfs_read_unlock(sb);
9574+
9575+ return ret;
9576+}
9577+
9578+struct super_operations unionfs_sops = {
9579+ .delete_inode = unionfs_delete_inode,
9580+ .put_super = unionfs_put_super,
9581+ .statfs = unionfs_statfs,
9582+ .remount_fs = unionfs_remount_fs,
9583+ .clear_inode = unionfs_clear_inode,
9584+ .umount_begin = unionfs_umount_begin,
9585+ .show_options = unionfs_show_options,
9586+ .write_inode = unionfs_write_inode,
9587+ .alloc_inode = unionfs_alloc_inode,
9588+ .destroy_inode = unionfs_destroy_inode,
9589+};
9590diff --git a/fs/unionfs/union.h b/fs/unionfs/union.h
9591new file mode 100644
9592index 0000000..1b9c3f7
9593--- /dev/null
9594+++ b/fs/unionfs/union.h
9595@@ -0,0 +1,607 @@
9596+/*
9597+ * Copyright (c) 2003-2008 Erez Zadok
9598+ * Copyright (c) 2003-2006 Charles P. Wright
9599+ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
9600+ * Copyright (c) 2005 Arun M. Krishnakumar
9601+ * Copyright (c) 2004-2006 David P. Quigley
9602+ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
9603+ * Copyright (c) 2003 Puja Gupta
9604+ * Copyright (c) 2003 Harikesavan Krishnan
9605+ * Copyright (c) 2003-2008 Stony Brook University
9606+ * Copyright (c) 2003-2008 The Research Foundation of SUNY
9607+ *
9608+ * This program is free software; you can redistribute it and/or modify
9609+ * it under the terms of the GNU General Public License version 2 as
9610+ * published by the Free Software Foundation.
9611+ */
9612+
9613+#ifndef _UNION_H_
9614+#define _UNION_H_
9615+
9616+#include <linux/dcache.h>
9617+#include <linux/file.h>
9618+#include <linux/list.h>
9619+#include <linux/fs.h>
9620+#include <linux/mm.h>
9621+#include <linux/module.h>
9622+#include <linux/mount.h>
9623+#include <linux/namei.h>
9624+#include <linux/page-flags.h>
9625+#include <linux/pagemap.h>
9626+#include <linux/poll.h>
9627+#include <linux/security.h>
9628+#include <linux/seq_file.h>
9629+#include <linux/slab.h>
9630+#include <linux/spinlock.h>
9631+#include <linux/smp_lock.h>
9632+#include <linux/statfs.h>
9633+#include <linux/string.h>
9634+#include <linux/vmalloc.h>
9635+#include <linux/writeback.h>
9636+#include <linux/buffer_head.h>
9637+#include <linux/xattr.h>
9638+#include <linux/fs_stack.h>
9639+#include <linux/magic.h>
9640+#include <linux/log2.h>
9641+#include <linux/poison.h>
9642+#include <linux/mman.h>
9643+#include <linux/backing-dev.h>
9644+#include <linux/splice.h>
9645+
9646+#include <asm/system.h>
9647+
9648+#include <linux/union_fs.h>
9649+
9650+/* the file system name */
9651+#define UNIONFS_NAME "unionfs"
9652+
9653+/* unionfs root inode number */
9654+#define UNIONFS_ROOT_INO 1
9655+
9656+/* number of times we try to get a unique temporary file name */
9657+#define GET_TMPNAM_MAX_RETRY 5
9658+
9659+/* maximum number of branches we support, to avoid memory blowup */
9660+#define UNIONFS_MAX_BRANCHES 128
9661+
9662+/* minimum time (seconds) required for time-based cache-coherency */
9663+#define UNIONFS_MIN_CC_TIME 3
9664+
9665+/* Operations vectors defined in specific files. */
9666+extern struct file_operations unionfs_main_fops;
9667+extern struct file_operations unionfs_dir_fops;
9668+extern struct inode_operations unionfs_main_iops;
9669+extern struct inode_operations unionfs_dir_iops;
9670+extern struct inode_operations unionfs_symlink_iops;
9671+extern struct super_operations unionfs_sops;
9672+extern struct dentry_operations unionfs_dops;
9673+extern struct address_space_operations unionfs_aops, unionfs_dummy_aops;
9674+extern struct vm_operations_struct unionfs_vm_ops;
9675+
9676+/* How long should an entry be allowed to persist */
9677+#define RDCACHE_JIFFIES (5*HZ)
9678+
9679+/* compatibility with Real-Time patches */
9680+#ifdef CONFIG_PREEMPT_RT
9681+# define unionfs_rw_semaphore compat_rw_semaphore
9682+#else /* not CONFIG_PREEMPT_RT */
9683+# define unionfs_rw_semaphore rw_semaphore
9684+#endif /* not CONFIG_PREEMPT_RT */
9685+
9686+/* file private data. */
9687+struct unionfs_file_info {
9688+ int bstart;
9689+ int bend;
9690+ atomic_t generation;
9691+
9692+ struct unionfs_dir_state *rdstate;
9693+ struct file **lower_files;
9694+ int *saved_branch_ids; /* IDs of branches when file was opened */
9695+ struct vm_operations_struct *lower_vm_ops;
9696+ bool wrote_to_file; /* for delayed copyup */
9697+};
9698+
9699+/* unionfs inode data in memory */
9700+struct unionfs_inode_info {
9701+ int bstart;
9702+ int bend;
9703+ atomic_t generation;
9704+ /* Stuff for readdir over NFS. */
9705+ spinlock_t rdlock;
9706+ struct list_head readdircache;
9707+ int rdcount;
9708+ int hashsize;
9709+ int cookie;
9710+
9711+ /* The lower inodes */
9712+ struct inode **lower_inodes;
9713+
9714+ struct inode vfs_inode;
9715+};
9716+
9717+/* unionfs dentry data in memory */
9718+struct unionfs_dentry_info {
9719+ /*
9720+ * The semaphore is used to lock the dentry as soon as we get into a
9721+ * unionfs function from the VFS. Our lock ordering is that children
9722+ * go before their parents.
9723+ */
9724+ struct mutex lock;
9725+ int bstart;
9726+ int bend;
9727+ int bopaque;
9728+ int bcount;
9729+ atomic_t generation;
9730+ struct path *lower_paths;
9731+};
9732+
9733+/* These are the pointers to our various objects. */
9734+struct unionfs_data {
9735+ struct super_block *sb; /* lower super_block */
9736+ atomic_t open_files; /* number of open files on branch */
9737+ int branchperms;
9738+ int branch_id; /* unique branch ID at re/mount time */
9739+};
9740+
9741+/* unionfs super-block data in memory */
9742+struct unionfs_sb_info {
9743+ int bend;
9744+
9745+ atomic_t generation;
9746+
9747+ /*
9748+ * This rwsem is used to make sure that a branch management
9749+ * operation...
9750+ * 1) will not begin before all currently in-flight operations
9751+ * complete.
9752+ * 2) any new operations do not execute until the currently
9753+ * running branch management operation completes.
9754+ *
9755+ * The write_lock_owner records the PID of the task which grabbed
9756+ * the rw_sem for writing. If the same task also tries to grab the
9757+ * read lock, we allow it. This prevents a self-deadlock when
9758+ * branch-management is used on a pivot_root'ed union, because we
9759+ * have to ->lookup paths which belong to the same union.
9760+ */
9761+ struct unionfs_rw_semaphore rwsem;
9762+ pid_t write_lock_owner; /* PID of rw_sem owner (write lock) */
9763+ int high_branch_id; /* last unique branch ID given */
9764+ char *dev_name; /* to identify different unions in pr_debug */
9765+ struct unionfs_data *data;
9766+};
9767+
9768+/*
9769+ * structure for making the linked list of entries by readdir on left branch
9770+ * to compare with entries on right branch
9771+ */
9772+struct filldir_node {
9773+ struct list_head file_list; /* list for directory entries */
9774+ char *name; /* name entry */
9775+ int hash; /* name hash */
9776+ int namelen; /* name len since name is not 0 terminated */
9777+
9778+ /*
9779+ * we can check for duplicate whiteouts and files in the same branch
9780+ * in order to return -EIO.
9781+ */
9782+ int bindex;
9783+
9784+ /* is this a whiteout entry? */
9785+ int whiteout;
9786+
9787+ /* Inline name, so we don't need to separately kmalloc small ones */
9788+ char iname[DNAME_INLINE_LEN_MIN];
9789+};
9790+
9791+/* Directory hash table. */
9792+struct unionfs_dir_state {
9793+ unsigned int cookie; /* the cookie, based off of rdversion */
9794+ unsigned int offset; /* The entry we have returned. */
9795+ int bindex;
9796+ loff_t dirpos; /* offset within the lower level directory */
9797+ int size; /* How big is the hash table? */
9798+ int hashentries; /* How many entries have been inserted? */
9799+ unsigned long access;
9800+
9801+ /* This cache list is used when the inode keeps us around. */
9802+ struct list_head cache;
9803+ struct list_head list[0];
9804+};
9805+
9806+/* externs needed for fanout.h or sioq.h */
9807+extern int unionfs_get_nlinks(const struct inode *inode);
9808+extern void unionfs_copy_attr_times(struct inode *upper);
9809+extern void unionfs_copy_attr_all(struct inode *dest, const struct inode *src);
9810+
9811+/* include miscellaneous macros */
9812+#include "fanout.h"
9813+#include "sioq.h"
9814+
9815+/* externs for cache creation/deletion routines */
9816+extern void unionfs_destroy_filldir_cache(void);
9817+extern int unionfs_init_filldir_cache(void);
9818+extern int unionfs_init_inode_cache(void);
9819+extern void unionfs_destroy_inode_cache(void);
9820+extern int unionfs_init_dentry_cache(void);
9821+extern void unionfs_destroy_dentry_cache(void);
9822+
9823+/* Initialize and free readdir-specific state. */
9824+extern int init_rdstate(struct file *file);
9825+extern struct unionfs_dir_state *alloc_rdstate(struct inode *inode,
9826+ int bindex);
9827+extern struct unionfs_dir_state *find_rdstate(struct inode *inode,
9828+ loff_t fpos);
9829+extern void free_rdstate(struct unionfs_dir_state *state);
9830+extern int add_filldir_node(struct unionfs_dir_state *rdstate,
9831+ const char *name, int namelen, int bindex,
9832+ int whiteout);
9833+extern struct filldir_node *find_filldir_node(struct unionfs_dir_state *rdstate,
9834+ const char *name, int namelen,
9835+ int is_whiteout);
9836+
9837+extern struct dentry **alloc_new_dentries(int objs);
9838+extern struct unionfs_data *alloc_new_data(int objs);
9839+
9840+/* We can only use 32-bits of offset for rdstate --- blech! */
9841+#define DIREOF (0xfffff)
9842+#define RDOFFBITS 20 /* This is the number of bits in DIREOF. */
9843+#define MAXRDCOOKIE (0xfff)
9844+/* Turn an rdstate into an offset. */
9845+static inline off_t rdstate2offset(struct unionfs_dir_state *buf)
9846+{
9847+ off_t tmp;
9848+
9849+ tmp = ((buf->cookie & MAXRDCOOKIE) << RDOFFBITS)
9850+ | (buf->offset & DIREOF);
9851+ return tmp;
9852+}
9853+
9854+/* Macros for locking a super_block. */
9855+enum unionfs_super_lock_class {
9856+ UNIONFS_SMUTEX_NORMAL,
9857+ UNIONFS_SMUTEX_PARENT, /* when locking on behalf of file */
9858+ UNIONFS_SMUTEX_CHILD, /* when locking on behalf of dentry */
9859+};
9860+static inline void unionfs_read_lock(struct super_block *sb, int subclass)
9861+{
9862+ if (UNIONFS_SB(sb)->write_lock_owner &&
9863+ UNIONFS_SB(sb)->write_lock_owner == current->pid)
9864+ return;
9865+ down_read_nested(&UNIONFS_SB(sb)->rwsem, subclass);
9866+}
9867+static inline void unionfs_read_unlock(struct super_block *sb)
9868+{
9869+ if (UNIONFS_SB(sb)->write_lock_owner &&
9870+ UNIONFS_SB(sb)->write_lock_owner == current->pid)
9871+ return;
9872+ up_read(&UNIONFS_SB(sb)->rwsem);
9873+}
9874+static inline void unionfs_write_lock(struct super_block *sb)
9875+{
9876+ down_write(&UNIONFS_SB(sb)->rwsem);
9877+ UNIONFS_SB(sb)->write_lock_owner = current->pid;
9878+}
9879+static inline void unionfs_write_unlock(struct super_block *sb)
9880+{
9881+ up_write(&UNIONFS_SB(sb)->rwsem);
9882+ UNIONFS_SB(sb)->write_lock_owner = 0;
9883+}
9884+
9885+static inline void unionfs_double_lock_dentry(struct dentry *d1,
9886+ struct dentry *d2)
9887+{
9888+ BUG_ON(d1 == d2);
9889+ if (d1 < d2) {
9890+ unionfs_lock_dentry(d2, UNIONFS_DMUTEX_CHILD);
9891+ unionfs_lock_dentry(d1, UNIONFS_DMUTEX_PARENT);
9892+ } else {
9893+ unionfs_lock_dentry(d1, UNIONFS_DMUTEX_CHILD);
9894+ unionfs_lock_dentry(d2, UNIONFS_DMUTEX_PARENT);
9895+ }
9896+}
9897+
9898+extern int new_dentry_private_data(struct dentry *dentry, int subclass);
9899+extern int realloc_dentry_private_data(struct dentry *dentry);
9900+extern void free_dentry_private_data(struct dentry *dentry);
9901+extern void update_bstart(struct dentry *dentry);
9902+extern int init_lower_nd(struct nameidata *nd, unsigned int flags);
9903+extern void release_lower_nd(struct nameidata *nd, int err);
9904+
9905+/*
9906+ * EXTERNALS:
9907+ */
9908+
9909+/* replicates the directory structure up to given dentry in given branch */
9910+extern struct dentry *create_parents(struct inode *dir, struct dentry *dentry,
9911+ const char *name, int bindex);
9912+
9913+/* partial lookup */
9914+extern int unionfs_partial_lookup(struct dentry *dentry);
9915+extern struct dentry *unionfs_lookup_full(struct dentry *dentry,
9916+ struct nameidata *nd_unused,
9917+ int lookupmode);
9918+
9919+/* copies a file from dbstart to newbindex branch */
9920+extern int copyup_file(struct inode *dir, struct file *file, int bstart,
9921+ int newbindex, loff_t size);
9922+extern int copyup_named_file(struct inode *dir, struct file *file,
9923+ char *name, int bstart, int new_bindex,
9924+ loff_t len);
9925+/* copies a dentry from dbstart to newbindex branch */
9926+extern int copyup_dentry(struct inode *dir, struct dentry *dentry,
9927+ int bstart, int new_bindex, const char *name,
9928+ int namelen, struct file **copyup_file, loff_t len);
9929+/* helper functions for post-copyup actions */
9930+extern void unionfs_postcopyup_setmnt(struct dentry *dentry);
9931+extern void unionfs_postcopyup_release(struct dentry *dentry);
9932+
9933+/* Is this directory empty: 0 if it is empty, -ENOTEMPTY if not. */
9934+extern int check_empty(struct dentry *dentry,
9935+ struct unionfs_dir_state **namelist);
9936+/* whiteout and opaque directory helpers */
9937+extern char *alloc_whname(const char *name, int len);
9938+extern bool is_whiteout_name(char **namep, int *namelenp);
9939+extern bool is_validname(const char *name);
9940+extern struct dentry *lookup_whiteout(const char *name,
9941+ struct dentry *lower_parent);
9942+extern struct dentry *find_first_whiteout(struct dentry *dentry);
9943+extern int unlink_whiteout(struct dentry *wh_dentry);
9944+extern int check_unlink_whiteout(struct dentry *dentry,
9945+ struct dentry *lower_dentry, int bindex);
9946+extern int create_whiteout(struct dentry *dentry, int start);
9947+extern int delete_whiteouts(struct dentry *dentry, int bindex,
9948+ struct unionfs_dir_state *namelist);
9949+extern int is_opaque_dir(struct dentry *dentry, int bindex);
9950+extern int make_dir_opaque(struct dentry *dir, int bindex);
9951+extern void unionfs_set_max_namelen(long *namelen);
9952+
9953+extern void unionfs_reinterpose(struct dentry *this_dentry);
9954+extern struct super_block *unionfs_duplicate_super(struct super_block *sb);
9955+
9956+/* Locking functions. */
9957+extern int unionfs_setlk(struct file *file, int cmd, struct file_lock *fl);
9958+extern int unionfs_getlk(struct file *file, struct file_lock *fl);
9959+
9960+/* Common file operations. */
9961+extern int unionfs_file_revalidate(struct file *file, bool willwrite);
9962+extern int unionfs_file_revalidate_locked(struct file *file, bool willwrite);
9963+extern int unionfs_open(struct inode *inode, struct file *file);
9964+extern int unionfs_file_release(struct inode *inode, struct file *file);
9965+extern int unionfs_flush(struct file *file, fl_owner_t id);
9966+extern long unionfs_ioctl(struct file *file, unsigned int cmd,
9967+ unsigned long arg);
9968+extern int unionfs_fsync(struct file *file, struct dentry *dentry,
9969+ int datasync);
9970+extern int unionfs_fasync(int fd, struct file *file, int flag);
9971+
9972+/* Inode operations */
9973+extern struct inode *unionfs_iget(struct super_block *sb, unsigned long ino);
9974+extern int unionfs_rename(struct inode *old_dir, struct dentry *old_dentry,
9975+ struct inode *new_dir, struct dentry *new_dentry);
9976+extern int unionfs_unlink(struct inode *dir, struct dentry *dentry);
9977+extern int unionfs_rmdir(struct inode *dir, struct dentry *dentry);
9978+
9979+extern bool __unionfs_d_revalidate_one_locked(struct dentry *dentry,
9980+ struct nameidata *nd,
9981+ bool willwrite);
9982+extern bool __unionfs_d_revalidate_chain(struct dentry *dentry,
9983+ struct nameidata *nd, bool willwrite);
9984+extern bool is_negative_lower(const struct dentry *dentry);
9985+extern bool is_newer_lower(const struct dentry *dentry);
9986+extern void purge_sb_data(struct super_block *sb);
9987+
9988+/* The values for unionfs_interpose's flag. */
9989+#define INTERPOSE_DEFAULT 0
9990+#define INTERPOSE_LOOKUP 1
9991+#define INTERPOSE_REVAL 2
9992+#define INTERPOSE_REVAL_NEG 3
9993+#define INTERPOSE_PARTIAL 4
9994+
9995+extern struct dentry *unionfs_interpose(struct dentry *this_dentry,
9996+ struct super_block *sb, int flag);
9997+
9998+#ifdef CONFIG_UNION_FS_XATTR
9999+/* Extended attribute functions. */
10000+extern void *unionfs_xattr_alloc(size_t size, size_t limit);
10001+static inline void unionfs_xattr_kfree(const void *p)
10002+{
10003+ kfree(p);
10004+}
10005+extern ssize_t unionfs_getxattr(struct dentry *dentry, const char *name,
10006+ void *value, size_t size);
10007+extern int unionfs_removexattr(struct dentry *dentry, const char *name);
10008+extern ssize_t unionfs_listxattr(struct dentry *dentry, char *list,
10009+ size_t size);
10010+extern int unionfs_setxattr(struct dentry *dentry, const char *name,
10011+ const void *value, size_t size, int flags);
10012+#endif /* CONFIG_UNION_FS_XATTR */
10013+
10014+/* The root directory is unhashed, but isn't deleted. */
10015+static inline int d_deleted(struct dentry *d)
10016+{
10017+ return d_unhashed(d) && (d != d->d_sb->s_root);
10018+}
10019+
10020+/* unionfs_permission, check if we should bypass error to facilitate copyup */
10021+#define IS_COPYUP_ERR(err) ((err) == -EROFS)
10022+
10023+/* unionfs_open, check if we need to copyup the file */
10024+#define OPEN_WRITE_FLAGS (O_WRONLY | O_RDWR | O_APPEND)
10025+#define IS_WRITE_FLAG(flag) ((flag) & OPEN_WRITE_FLAGS)
10026+
10027+static inline int branchperms(const struct super_block *sb, int index)
10028+{
10029+ BUG_ON(index < 0);
10030+ return UNIONFS_SB(sb)->data[index].branchperms;
10031+}
10032+
10033+static inline int set_branchperms(struct super_block *sb, int index, int perms)
10034+{
10035+ BUG_ON(index < 0);
10036+ UNIONFS_SB(sb)->data[index].branchperms = perms;
10037+ return perms;
10038+}
10039+
10040+/* Is this file on a read-only branch? */
10041+static inline int is_robranch_super(const struct super_block *sb, int index)
10042+{
10043+ int ret;
10044+
10045+ ret = (!(branchperms(sb, index) & MAY_WRITE)) ? -EROFS : 0;
10046+ return ret;
10047+}
10048+
10049+/* Is this file on a read-only branch? */
10050+static inline int is_robranch_idx(const struct dentry *dentry, int index)
10051+{
10052+ struct super_block *lower_sb;
10053+
10054+ BUG_ON(index < 0);
10055+
10056+ if (!(branchperms(dentry->d_sb, index) & MAY_WRITE))
10057+ return -EROFS;
10058+
10059+ lower_sb = unionfs_lower_super_idx(dentry->d_sb, index);
10060+ BUG_ON(lower_sb == NULL);
10061+ /*
10062+ * test sb flags directly, not IS_RDONLY(lower_inode) because the
10063+ * lower_dentry could be a negative.
10064+ */
10065+ if (lower_sb->s_flags & MS_RDONLY)
10066+ return -EROFS;
10067+
10068+ return 0;
10069+}
10070+
10071+static inline int is_robranch(const struct dentry *dentry)
10072+{
10073+ int index;
10074+
10075+ index = UNIONFS_D(dentry)->bstart;
10076+ BUG_ON(index < 0);
10077+
10078+ return is_robranch_idx(dentry, index);
10079+}
10080+
10081+/*
10082+ * EXTERNALS:
10083+ */
10084+extern int check_branch(struct nameidata *nd);
10085+extern int parse_branch_mode(const char *name, int *perms);
10086+
10087+/* locking helpers */
10088+static inline struct dentry *lock_parent(struct dentry *dentry)
10089+{
10090+ struct dentry *dir = dget_parent(dentry);
10091+ mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT);
10092+ return dir;
10093+}
10094+static inline struct dentry *lock_parent_wh(struct dentry *dentry)
10095+{
10096+ struct dentry *dir = dget_parent(dentry);
10097+
10098+ mutex_lock_nested(&dir->d_inode->i_mutex, UNIONFS_DMUTEX_WHITEOUT);
10099+ return dir;
10100+}
10101+
10102+static inline void unlock_dir(struct dentry *dir)
10103+{
10104+ mutex_unlock(&dir->d_inode->i_mutex);
10105+ dput(dir);
10106+}
10107+
10108+static inline struct vfsmount *unionfs_mntget(struct dentry *dentry,
10109+ int bindex)
10110+{
10111+ struct vfsmount *mnt;
10112+
10113+ BUG_ON(!dentry || bindex < 0);
10114+
10115+ mnt = mntget(unionfs_lower_mnt_idx(dentry, bindex));
10116+#ifdef CONFIG_UNION_FS_DEBUG
10117+ if (!mnt)
10118+ pr_debug("unionfs: mntget: mnt=%p bindex=%d\n",
10119+ mnt, bindex);
10120+#endif /* CONFIG_UNION_FS_DEBUG */
10121+
10122+ return mnt;
10123+}
10124+
10125+static inline void unionfs_mntput(struct dentry *dentry, int bindex)
10126+{
10127+ struct vfsmount *mnt;
10128+
10129+ if (!dentry && bindex < 0)
10130+ return;
10131+ BUG_ON(!dentry || bindex < 0);
10132+
10133+ mnt = unionfs_lower_mnt_idx(dentry, bindex);
10134+#ifdef CONFIG_UNION_FS_DEBUG
10135+ /*
10136+ * Directories can have NULL lower objects in between start/end, but
10137+ * NOT if at the start/end range. We cannot verify that this dentry
10138+ * is a type=DIR, because it may already be a negative dentry. But
10139+ * if dbstart is greater than dbend, we know that this couldn't have
10140+ * been a regular file: it had to have been a directory.
10141+ */
10142+ if (!mnt && !(bindex > dbstart(dentry) && bindex < dbend(dentry)))
10143+ pr_debug("unionfs: mntput: mnt=%p bindex=%d\n", mnt, bindex);
10144+#endif /* CONFIG_UNION_FS_DEBUG */
10145+ mntput(mnt);
10146+}
10147+
10148+#ifdef CONFIG_UNION_FS_DEBUG
10149+
10150+/* useful for tracking code reachability */
10151+#define UDBG pr_debug("DBG:%s:%s:%d\n", __FILE__, __func__, __LINE__)
10152+
10153+#define unionfs_check_inode(i) __unionfs_check_inode((i), \
10154+ __FILE__, __func__, __LINE__)
10155+#define unionfs_check_dentry(d) __unionfs_check_dentry((d), \
10156+ __FILE__, __func__, __LINE__)
10157+#define unionfs_check_file(f) __unionfs_check_file((f), \
10158+ __FILE__, __func__, __LINE__)
10159+#define unionfs_check_nd(n) __unionfs_check_nd((n), \
10160+ __FILE__, __func__, __LINE__)
10161+#define show_branch_counts(sb) __show_branch_counts((sb), \
10162+ __FILE__, __func__, __LINE__)
10163+#define show_inode_times(i) __show_inode_times((i), \
10164+ __FILE__, __func__, __LINE__)
10165+#define show_dinode_times(d) __show_dinode_times((d), \
10166+ __FILE__, __func__, __LINE__)
10167+#define show_inode_counts(i) __show_inode_counts((i), \
10168+ __FILE__, __func__, __LINE__)
10169+
10170+extern void __unionfs_check_inode(const struct inode *inode, const char *fname,
10171+ const char *fxn, int line);
10172+extern void __unionfs_check_dentry(const struct dentry *dentry,
10173+ const char *fname, const char *fxn,
10174+ int line);
10175+extern void __unionfs_check_file(const struct file *file,
10176+ const char *fname, const char *fxn, int line);
10177+extern void __unionfs_check_nd(const struct nameidata *nd,
10178+ const char *fname, const char *fxn, int line);
10179+extern void __show_branch_counts(const struct super_block *sb,
10180+ const char *file, const char *fxn, int line);
10181+extern void __show_inode_times(const struct inode *inode,
10182+ const char *file, const char *fxn, int line);
10183+extern void __show_dinode_times(const struct dentry *dentry,
10184+ const char *file, const char *fxn, int line);
10185+extern void __show_inode_counts(const struct inode *inode,
10186+ const char *file, const char *fxn, int line);
10187+
10188+#else /* not CONFIG_UNION_FS_DEBUG */
10189+
10190+/* we leave useful hooks for these check functions throughout the code */
10191+#define unionfs_check_inode(i) do { } while (0)
10192+#define unionfs_check_dentry(d) do { } while (0)
10193+#define unionfs_check_file(f) do { } while (0)
10194+#define unionfs_check_nd(n) do { } while (0)
10195+#define show_branch_counts(sb) do { } while (0)
10196+#define show_inode_times(i) do { } while (0)
10197+#define show_dinode_times(d) do { } while (0)
10198+#define show_inode_counts(i) do { } while (0)
10199+
10200+#endif /* not CONFIG_UNION_FS_DEBUG */
10201+
10202+#endif /* not _UNION_H_ */
10203diff --git a/fs/unionfs/unlink.c b/fs/unionfs/unlink.c
10204new file mode 100644
10205index 0000000..623f68d
10206--- /dev/null
10207+++ b/fs/unionfs/unlink.c
10208@@ -0,0 +1,277 @@
10209+/*
10210+ * Copyright (c) 2003-2008 Erez Zadok
10211+ * Copyright (c) 2003-2006 Charles P. Wright
10212+ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
10213+ * Copyright (c) 2005-2006 Junjiro Okajima
10214+ * Copyright (c) 2005 Arun M. Krishnakumar
10215+ * Copyright (c) 2004-2006 David P. Quigley
10216+ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
10217+ * Copyright (c) 2003 Puja Gupta
10218+ * Copyright (c) 2003 Harikesavan Krishnan
10219+ * Copyright (c) 2003-2008 Stony Brook University
10220+ * Copyright (c) 2003-2008 The Research Foundation of SUNY
10221+ *
10222+ * This program is free software; you can redistribute it and/or modify
10223+ * it under the terms of the GNU General Public License version 2 as
10224+ * published by the Free Software Foundation.
10225+ */
10226+
10227+#include "union.h"
10228+
10229+/*
10230+ * Helper function for Unionfs's unlink operation.
10231+ *
10232+ * The main goal of this function is to optimize the unlinking of non-dir
10233+ * objects in unionfs by deleting all possible lower inode objects from the
10234+ * underlying branches having same dentry name as the non-dir dentry on
10235+ * which this unlink operation is called. This way we delete as many lower
10236+ * inodes as possible, and save space. Whiteouts need to be created in
10237+ * branch0 only if unlinking fails on any of the lower branch other than
10238+ * branch0, or if a lower branch is marked read-only.
10239+ *
10240+ * Also, while unlinking a file, if we encounter any dir type entry in any
10241+ * intermediate branch, then we remove the directory by calling vfs_rmdir.
10242+ * The following special cases are also handled:
10243+
10244+ * (1) If an error occurs in branch0 during vfs_unlink, then we return
10245+ * appropriate error.
10246+ *
10247+ * (2) If we get an error during unlink in any of other lower branch other
10248+ * than branch0, then we create a whiteout in branch0.
10249+ *
10250+ * (3) If a whiteout already exists in any intermediate branch, we delete
10251+ * all possible inodes only up to that branch (this is an "opaqueness"
10252+ * as as per Documentation/filesystems/unionfs/concepts.txt).
10253+ *
10254+ */
10255+static int unionfs_unlink_whiteout(struct inode *dir, struct dentry *dentry)
10256+{
10257+ struct dentry *lower_dentry;
10258+ struct dentry *lower_dir_dentry;
10259+ int bindex;
10260+ int err = 0;
10261+
10262+ err = unionfs_partial_lookup(dentry);
10263+ if (err)
10264+ goto out;
10265+
10266+ /* trying to unlink all possible valid instances */
10267+ for (bindex = dbstart(dentry); bindex <= dbend(dentry); bindex++) {
10268+ lower_dentry = unionfs_lower_dentry_idx(dentry, bindex);
10269+ if (!lower_dentry || !lower_dentry->d_inode)
10270+ continue;
10271+
10272+ lower_dir_dentry = lock_parent(lower_dentry);
10273+
10274+ /* avoid destroying the lower inode if the object is in use */
10275+ dget(lower_dentry);
10276+ err = is_robranch_super(dentry->d_sb, bindex);
10277+ if (!err) {
10278+ /* see Documentation/filesystems/unionfs/issues.txt */
10279+ lockdep_off();
10280+ if (!S_ISDIR(lower_dentry->d_inode->i_mode))
10281+ err = vfs_unlink(lower_dir_dentry->d_inode,
10282+ lower_dentry);
10283+ else
10284+ err = vfs_rmdir(lower_dir_dentry->d_inode,
10285+ lower_dentry);
10286+ lockdep_on();
10287+ }
10288+
10289+ /* if lower object deletion succeeds, update inode's times */
10290+ if (!err)
10291+ unionfs_copy_attr_times(dentry->d_inode);
10292+ dput(lower_dentry);
10293+ fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode);
10294+ unlock_dir(lower_dir_dentry);
10295+
10296+ if (err)
10297+ break;
10298+ }
10299+
10300+ /*
10301+ * Create the whiteout in branch 0 (highest priority) only if (a)
10302+ * there was an error in any intermediate branch other than branch 0
10303+ * due to failure of vfs_unlink/vfs_rmdir or (b) a branch marked or
10304+ * mounted read-only.
10305+ */
10306+ if (err) {
10307+ if ((bindex == 0) ||
10308+ ((bindex == dbstart(dentry)) &&
10309+ (!IS_COPYUP_ERR(err))))
10310+ goto out;
10311+ else {
10312+ if (!IS_COPYUP_ERR(err))
10313+ pr_debug("unionfs: lower object deletion "
10314+ "failed in branch:%d\n", bindex);
10315+ err = create_whiteout(dentry, sbstart(dentry->d_sb));
10316+ }
10317+ }
10318+
10319+out:
10320+ if (!err)
10321+ inode_dec_link_count(dentry->d_inode);
10322+
10323+ /* We don't want to leave negative leftover dentries for revalidate. */
10324+ if (!err && (dbopaque(dentry) != -1))
10325+ update_bstart(dentry);
10326+
10327+ return err;
10328+}
10329+
10330+int unionfs_unlink(struct inode *dir, struct dentry *dentry)
10331+{
10332+ int err = 0;
10333+ struct inode *inode = dentry->d_inode;
10334+ int valid;
10335+
10336+ BUG_ON(S_ISDIR(inode->i_mode));
10337+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD);
10338+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
10339+ unionfs_lock_dentry(dentry->d_parent, UNIONFS_DMUTEX_PARENT);
10340+
10341+ valid = __unionfs_d_revalidate_chain(dentry->d_parent, NULL, false);
10342+ if (unlikely(!valid)) {
10343+ err = -ESTALE;
10344+ goto out;
10345+ }
10346+ valid = __unionfs_d_revalidate_one_locked(dentry, NULL, false);
10347+ if (unlikely(!valid)) {
10348+ err = -ESTALE;
10349+ goto out;
10350+ }
10351+ unionfs_check_dentry(dentry);
10352+
10353+ err = unionfs_unlink_whiteout(dir, dentry);
10354+ /* call d_drop so the system "forgets" about us */
10355+ if (!err) {
10356+ unionfs_postcopyup_release(dentry);
10357+ if (inode->i_nlink == 0) /* drop lower inodes */
10358+ iput_lowers_all(inode, false);
10359+ d_drop(dentry);
10360+ /*
10361+ * if unlink/whiteout succeeded, parent dir mtime has
10362+ * changed
10363+ */
10364+ unionfs_copy_attr_times(dir);
10365+ }
10366+
10367+out:
10368+ if (!err) {
10369+ unionfs_check_dentry(dentry);
10370+ unionfs_check_inode(dir);
10371+ }
10372+ unionfs_unlock_dentry(dentry->d_parent);
10373+ unionfs_unlock_dentry(dentry);
10374+ unionfs_read_unlock(dentry->d_sb);
10375+ return err;
10376+}
10377+
10378+static int unionfs_rmdir_first(struct inode *dir, struct dentry *dentry,
10379+ struct unionfs_dir_state *namelist)
10380+{
10381+ int err;
10382+ struct dentry *lower_dentry;
10383+ struct dentry *lower_dir_dentry = NULL;
10384+
10385+ /* Here we need to remove whiteout entries. */
10386+ err = delete_whiteouts(dentry, dbstart(dentry), namelist);
10387+ if (err)
10388+ goto out;
10389+
10390+ lower_dentry = unionfs_lower_dentry(dentry);
10391+
10392+ lower_dir_dentry = lock_parent(lower_dentry);
10393+
10394+ /* avoid destroying the lower inode if the file is in use */
10395+ dget(lower_dentry);
10396+ err = is_robranch(dentry);
10397+ if (!err) {
10398+ /* see Documentation/filesystems/unionfs/issues.txt */
10399+ lockdep_off();
10400+ err = vfs_rmdir(lower_dir_dentry->d_inode, lower_dentry);
10401+ lockdep_on();
10402+ }
10403+ dput(lower_dentry);
10404+
10405+ fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode);
10406+ /* propagate number of hard-links */
10407+ dentry->d_inode->i_nlink = unionfs_get_nlinks(dentry->d_inode);
10408+
10409+out:
10410+ if (lower_dir_dentry)
10411+ unlock_dir(lower_dir_dentry);
10412+ return err;
10413+}
10414+
10415+int unionfs_rmdir(struct inode *dir, struct dentry *dentry)
10416+{
10417+ int err = 0;
10418+ struct unionfs_dir_state *namelist = NULL;
10419+ int dstart, dend;
10420+
10421+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD);
10422+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
10423+
10424+ if (unlikely(!__unionfs_d_revalidate_chain(dentry, NULL, false))) {
10425+ err = -ESTALE;
10426+ goto out;
10427+ }
10428+ unionfs_check_dentry(dentry);
10429+
10430+ /* check if this unionfs directory is empty or not */
10431+ err = check_empty(dentry, &namelist);
10432+ if (err)
10433+ goto out;
10434+
10435+ err = unionfs_rmdir_first(dir, dentry, namelist);
10436+ dstart = dbstart(dentry);
10437+ dend = dbend(dentry);
10438+ /*
10439+ * We create a whiteout for the directory if there was an error to
10440+ * rmdir the first directory entry in the union. Otherwise, we
10441+ * create a whiteout only if there is no chance that a lower
10442+ * priority branch might also have the same named directory. IOW,
10443+ * if there is not another same-named directory at a lower priority
10444+ * branch, then we don't need to create a whiteout for it.
10445+ */
10446+ if (!err) {
10447+ if (dstart < dend)
10448+ err = create_whiteout(dentry, dstart);
10449+ } else {
10450+ int new_err;
10451+
10452+ if (dstart == 0)
10453+ goto out;
10454+
10455+ /* exit if the error returned was NOT -EROFS */
10456+ if (!IS_COPYUP_ERR(err))
10457+ goto out;
10458+
10459+ new_err = create_whiteout(dentry, dstart - 1);
10460+ if (new_err != -EEXIST)
10461+ err = new_err;
10462+ }
10463+
10464+out:
10465+ /*
10466+ * Drop references to lower dentry/inode so storage space for them
10467+ * can be reclaimed. Then, call d_drop so the system "forgets"
10468+ * about us.
10469+ */
10470+ if (!err) {
10471+ iput_lowers_all(dentry->d_inode, false);
10472+ dput(unionfs_lower_dentry_idx(dentry, dstart));
10473+ unionfs_set_lower_dentry_idx(dentry, dstart, NULL);
10474+ d_drop(dentry);
10475+ /* update our lower vfsmnts, in case a copyup took place */
10476+ unionfs_postcopyup_setmnt(dentry);
10477+ }
10478+
10479+ if (namelist)
10480+ free_rdstate(namelist);
10481+
10482+ unionfs_unlock_dentry(dentry);
10483+ unionfs_read_unlock(dentry->d_sb);
10484+ return err;
10485+}
10486diff --git a/fs/unionfs/whiteout.c b/fs/unionfs/whiteout.c
10487new file mode 100644
10488index 0000000..db7a21e
10489--- /dev/null
10490+++ b/fs/unionfs/whiteout.c
10491@@ -0,0 +1,577 @@
10492+/*
10493+ * Copyright (c) 2003-2008 Erez Zadok
10494+ * Copyright (c) 2003-2006 Charles P. Wright
10495+ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
10496+ * Copyright (c) 2005-2006 Junjiro Okajima
10497+ * Copyright (c) 2005 Arun M. Krishnakumar
10498+ * Copyright (c) 2004-2006 David P. Quigley
10499+ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
10500+ * Copyright (c) 2003 Puja Gupta
10501+ * Copyright (c) 2003 Harikesavan Krishnan
10502+ * Copyright (c) 2003-2008 Stony Brook University
10503+ * Copyright (c) 2003-2008 The Research Foundation of SUNY
10504+ *
10505+ * This program is free software; you can redistribute it and/or modify
10506+ * it under the terms of the GNU General Public License version 2 as
10507+ * published by the Free Software Foundation.
10508+ */
10509+
10510+#include "union.h"
10511+
10512+/*
10513+ * whiteout and opaque directory helpers
10514+ */
10515+
10516+/* What do we use for whiteouts. */
10517+#define UNIONFS_WHPFX ".wh."
10518+#define UNIONFS_WHLEN 4
10519+/*
10520+ * If a directory contains this file, then it is opaque. We start with the
10521+ * .wh. flag so that it is blocked by lookup.
10522+ */
10523+#define UNIONFS_DIR_OPAQUE_NAME "__dir_opaque"
10524+#define UNIONFS_DIR_OPAQUE UNIONFS_WHPFX UNIONFS_DIR_OPAQUE_NAME
10525+
10526+/* construct whiteout filename */
10527+char *alloc_whname(const char *name, int len)
10528+{
10529+ char *buf;
10530+
10531+ buf = kmalloc(len + UNIONFS_WHLEN + 1, GFP_KERNEL);
10532+ if (unlikely(!buf))
10533+ return ERR_PTR(-ENOMEM);
10534+
10535+ strcpy(buf, UNIONFS_WHPFX);
10536+ strlcat(buf, name, len + UNIONFS_WHLEN + 1);
10537+
10538+ return buf;
10539+}
10540+
10541+/*
10542+ * XXX: this can be inline or CPP macro, but is here to keep all whiteout
10543+ * code in one place.
10544+ */
10545+void unionfs_set_max_namelen(long *namelen)
10546+{
10547+ *namelen -= UNIONFS_WHLEN;
10548+}
10549+
10550+/* check if @namep is a whiteout, update @namep and @namelenp accordingly */
10551+bool is_whiteout_name(char **namep, int *namelenp)
10552+{
10553+ if (*namelenp > UNIONFS_WHLEN &&
10554+ !strncmp(*namep, UNIONFS_WHPFX, UNIONFS_WHLEN)) {
10555+ *namep += UNIONFS_WHLEN;
10556+ *namelenp -= UNIONFS_WHLEN;
10557+ return true;
10558+ }
10559+ return false;
10560+}
10561+
10562+/* is the filename valid == !(whiteout for a file or opaque dir marker) */
10563+bool is_validname(const char *name)
10564+{
10565+ if (!strncmp(name, UNIONFS_WHPFX, UNIONFS_WHLEN))
10566+ return false;
10567+ if (!strncmp(name, UNIONFS_DIR_OPAQUE_NAME,
10568+ sizeof(UNIONFS_DIR_OPAQUE_NAME) - 1))
10569+ return false;
10570+ return true;
10571+}
10572+
10573+/*
10574+ * Look for a whiteout @name in @lower_parent directory. If error, return
10575+ * ERR_PTR. Caller must dput() the returned dentry if not an error.
10576+ *
10577+ * XXX: some callers can reuse the whname allocated buffer to avoid repeated
10578+ * free then re-malloc calls. Need to provide a different API for those
10579+ * callers.
10580+ */
10581+struct dentry *lookup_whiteout(const char *name, struct dentry *lower_parent)
10582+{
10583+ char *whname = NULL;
10584+ int err = 0, namelen;
10585+ struct dentry *wh_dentry = NULL;
10586+
10587+ namelen = strlen(name);
10588+ whname = alloc_whname(name, namelen);
10589+ if (unlikely(IS_ERR(whname))) {
10590+ err = PTR_ERR(whname);
10591+ goto out;
10592+ }
10593+
10594+ /* check if whiteout exists in this branch: lookup .wh.foo */
10595+ wh_dentry = lookup_one_len(whname, lower_parent, strlen(whname));
10596+ if (IS_ERR(wh_dentry)) {
10597+ err = PTR_ERR(wh_dentry);
10598+ goto out;
10599+ }
10600+
10601+ /* check if negative dentry (ENOENT) */
10602+ if (!wh_dentry->d_inode)
10603+ goto out;
10604+
10605+ /* whiteout found: check if valid type */
10606+ if (!S_ISREG(wh_dentry->d_inode->i_mode)) {
10607+ printk(KERN_ERR "unionfs: invalid whiteout %s entry type %d\n",
10608+ whname, wh_dentry->d_inode->i_mode);
10609+ dput(wh_dentry);
10610+ err = -EIO;
10611+ goto out;
10612+ }
10613+
10614+out:
10615+ kfree(whname);
10616+ if (err)
10617+ wh_dentry = ERR_PTR(err);
10618+ return wh_dentry;
10619+}
10620+
10621+/* find and return first whiteout in parent directory, else ENOENT */
10622+struct dentry *find_first_whiteout(struct dentry *dentry)
10623+{
10624+ int bindex, bstart, bend;
10625+ struct dentry *parent, *lower_parent, *wh_dentry;
10626+
10627+ parent = dget_parent(dentry);
10628+ unionfs_lock_dentry(parent, UNIONFS_DMUTEX_WHITEOUT);
10629+ bstart = dbstart(parent);
10630+ bend = dbend(parent);
10631+ wh_dentry = ERR_PTR(-ENOENT);
10632+
10633+ for (bindex = bstart; bindex <= bend; bindex++) {
10634+ lower_parent = unionfs_lower_dentry_idx(parent, bindex);
10635+ if (!lower_parent)
10636+ continue;
10637+ wh_dentry = lookup_whiteout(dentry->d_name.name, lower_parent);
10638+ if (IS_ERR(wh_dentry))
10639+ continue;
10640+ if (wh_dentry->d_inode)
10641+ break;
10642+ dput(wh_dentry);
10643+ wh_dentry = ERR_PTR(-ENOENT);
10644+ }
10645+ unionfs_unlock_dentry(parent);
10646+ dput(parent);
10647+
10648+ return wh_dentry;
10649+}
10650+
10651+/*
10652+ * Unlink a whiteout dentry. Returns 0 or -errno. Caller must hold and
10653+ * release dentry reference.
10654+ */
10655+int unlink_whiteout(struct dentry *wh_dentry)
10656+{
10657+ int err;
10658+ struct dentry *lower_dir_dentry;
10659+
10660+ /* dget and lock parent dentry */
10661+ lower_dir_dentry = lock_parent_wh(wh_dentry);
10662+
10663+ /* see Documentation/filesystems/unionfs/issues.txt */
10664+ lockdep_off();
10665+ err = vfs_unlink(lower_dir_dentry->d_inode, wh_dentry);
10666+ lockdep_on();
10667+ unlock_dir(lower_dir_dentry);
10668+
10669+ /*
10670+ * Whiteouts are special files and should be deleted no matter what
10671+ * (as if they never existed), in order to allow this create
10672+ * operation to succeed. This is especially important in sticky
10673+ * directories: a whiteout may have been created by one user, but
10674+ * the newly created file may be created by another user.
10675+ * Therefore, in order to maintain Unix semantics, if the vfs_unlink
10676+ * above failed, then we have to try to directly unlink the
10677+ * whiteout. Note: in the ODF version of unionfs, whiteout are
10678+ * handled much more cleanly.
10679+ */
10680+ if (err == -EPERM) {
10681+ struct inode *inode = lower_dir_dentry->d_inode;
10682+ err = inode->i_op->unlink(inode, wh_dentry);
10683+ }
10684+ if (err)
10685+ printk(KERN_ERR "unionfs: could not unlink whiteout %s, "
10686+ "err = %d\n", wh_dentry->d_name.name, err);
10687+
10688+ return err;
10689+
10690+}
10691+
10692+/*
10693+ * Helper function when creating new objects (create, symlink, mknod, etc.).
10694+ * Checks to see if there's a whiteout in @lower_dentry's parent directory,
10695+ * whose name is taken from @dentry. Then tries to remove that whiteout, if
10696+ * found. If <dentry,bindex> is a branch marked readonly, return -EROFS.
10697+ * If it finds both a regular file and a whiteout, return -EIO (this should
10698+ * never happen).
10699+ *
10700+ * Return 0 if no whiteout was found. Return 1 if one was found and
10701+ * successfully removed. Therefore a value >= 0 tells the caller that
10702+ * @lower_dentry belongs to a good branch to create the new object in).
10703+ * Return -ERRNO if an error occurred during whiteout lookup or in trying to
10704+ * unlink the whiteout.
10705+ */
10706+int check_unlink_whiteout(struct dentry *dentry, struct dentry *lower_dentry,
10707+ int bindex)
10708+{
10709+ int err;
10710+ struct dentry *wh_dentry = NULL;
10711+ struct dentry *lower_dir_dentry = NULL;
10712+
10713+ /* look for whiteout dentry first */
10714+ lower_dir_dentry = dget_parent(lower_dentry);
10715+ wh_dentry = lookup_whiteout(dentry->d_name.name, lower_dir_dentry);
10716+ dput(lower_dir_dentry);
10717+ if (IS_ERR(wh_dentry)) {
10718+ err = PTR_ERR(wh_dentry);
10719+ goto out;
10720+ }
10721+
10722+ if (!wh_dentry->d_inode) { /* no whiteout exists*/
10723+ err = 0;
10724+ goto out_dput;
10725+ }
10726+
10727+ /* check if regular file and whiteout were both found */
10728+ if (unlikely(lower_dentry->d_inode)) {
10729+ err = -EIO;
10730+ printk(KERN_ERR "unionfs: found both whiteout and regular "
10731+ "file in directory %s (branch %d)\n",
10732+ lower_dentry->d_parent->d_name.name, bindex);
10733+ goto out_dput;
10734+ }
10735+
10736+ /* check if branch is writeable */
10737+ err = is_robranch_super(dentry->d_sb, bindex);
10738+ if (err)
10739+ goto out_dput;
10740+
10741+ /* .wh.foo has been found, so let's unlink it */
10742+ err = unlink_whiteout(wh_dentry);
10743+ if (!err)
10744+ err = 1; /* a whiteout was found and successfully removed */
10745+out_dput:
10746+ dput(wh_dentry);
10747+out:
10748+ return err;
10749+}
10750+
10751+/*
10752+ * Pass an unionfs dentry and an index. It will try to create a whiteout
10753+ * for the filename in dentry, and will try in branch 'index'. On error,
10754+ * it will proceed to a branch to the left.
10755+ */
10756+int create_whiteout(struct dentry *dentry, int start)
10757+{
10758+ int bstart, bend, bindex;
10759+ struct dentry *lower_dir_dentry;
10760+ struct dentry *lower_dentry;
10761+ struct dentry *lower_wh_dentry;
10762+ struct nameidata nd;
10763+ char *name = NULL;
10764+ int err = -EINVAL;
10765+
10766+ verify_locked(dentry);
10767+
10768+ bstart = dbstart(dentry);
10769+ bend = dbend(dentry);
10770+
10771+ /* create dentry's whiteout equivalent */
10772+ name = alloc_whname(dentry->d_name.name, dentry->d_name.len);
10773+ if (unlikely(IS_ERR(name))) {
10774+ err = PTR_ERR(name);
10775+ goto out;
10776+ }
10777+
10778+ for (bindex = start; bindex >= 0; bindex--) {
10779+ lower_dentry = unionfs_lower_dentry_idx(dentry, bindex);
10780+
10781+ if (!lower_dentry) {
10782+ /*
10783+ * if lower dentry is not present, create the
10784+ * entire lower dentry directory structure and go
10785+ * ahead. Since we want to just create whiteout, we
10786+ * only want the parent dentry, and hence get rid of
10787+ * this dentry.
10788+ */
10789+ lower_dentry = create_parents(dentry->d_inode,
10790+ dentry,
10791+ dentry->d_name.name,
10792+ bindex);
10793+ if (!lower_dentry || IS_ERR(lower_dentry)) {
10794+ int ret = PTR_ERR(lower_dentry);
10795+ if (!IS_COPYUP_ERR(ret))
10796+ printk(KERN_ERR
10797+ "unionfs: create_parents for "
10798+ "whiteout failed: bindex=%d "
10799+ "err=%d\n", bindex, ret);
10800+ continue;
10801+ }
10802+ }
10803+
10804+ lower_wh_dentry =
10805+ lookup_one_len(name, lower_dentry->d_parent,
10806+ dentry->d_name.len + UNIONFS_WHLEN);
10807+ if (IS_ERR(lower_wh_dentry))
10808+ continue;
10809+
10810+ /*
10811+ * The whiteout already exists. This used to be impossible,
10812+ * but now is possible because of opaqueness.
10813+ */
10814+ if (lower_wh_dentry->d_inode) {
10815+ dput(lower_wh_dentry);
10816+ err = 0;
10817+ goto out;
10818+ }
10819+
10820+ err = init_lower_nd(&nd, LOOKUP_CREATE);
10821+ if (unlikely(err < 0))
10822+ goto out;
10823+ lower_dir_dentry = lock_parent_wh(lower_wh_dentry);
10824+ err = is_robranch_super(dentry->d_sb, bindex);
10825+ if (!err)
10826+ err = vfs_create(lower_dir_dentry->d_inode,
10827+ lower_wh_dentry,
10828+ ~current->fs->umask & S_IRUGO,
10829+ &nd);
10830+ unlock_dir(lower_dir_dentry);
10831+ dput(lower_wh_dentry);
10832+ release_lower_nd(&nd, err);
10833+
10834+ if (!err || !IS_COPYUP_ERR(err))
10835+ break;
10836+ }
10837+
10838+ /* set dbopaque so that lookup will not proceed after this branch */
10839+ if (!err)
10840+ dbopaque(dentry) = bindex;
10841+
10842+out:
10843+ kfree(name);
10844+ return err;
10845+}
10846+
10847+/*
10848+ * Delete all of the whiteouts in a given directory for rmdir.
10849+ *
10850+ * lower directory inode should be locked
10851+ */
10852+static int do_delete_whiteouts(struct dentry *dentry, int bindex,
10853+ struct unionfs_dir_state *namelist)
10854+{
10855+ int err = 0;
10856+ struct dentry *lower_dir_dentry = NULL;
10857+ struct dentry *lower_dentry;
10858+ char *name = NULL, *p;
10859+ struct inode *lower_dir;
10860+ int i;
10861+ struct list_head *pos;
10862+ struct filldir_node *cursor;
10863+
10864+ /* Find out lower parent dentry */
10865+ lower_dir_dentry = unionfs_lower_dentry_idx(dentry, bindex);
10866+ BUG_ON(!S_ISDIR(lower_dir_dentry->d_inode->i_mode));
10867+ lower_dir = lower_dir_dentry->d_inode;
10868+ BUG_ON(!S_ISDIR(lower_dir->i_mode));
10869+
10870+ err = -ENOMEM;
10871+ name = __getname();
10872+ if (unlikely(!name))
10873+ goto out;
10874+ strcpy(name, UNIONFS_WHPFX);
10875+ p = name + UNIONFS_WHLEN;
10876+
10877+ err = 0;
10878+ for (i = 0; !err && i < namelist->size; i++) {
10879+ list_for_each(pos, &namelist->list[i]) {
10880+ cursor =
10881+ list_entry(pos, struct filldir_node,
10882+ file_list);
10883+ /* Only operate on whiteouts in this branch. */
10884+ if (cursor->bindex != bindex)
10885+ continue;
10886+ if (!cursor->whiteout)
10887+ continue;
10888+
10889+ strlcpy(p, cursor->name, PATH_MAX - UNIONFS_WHLEN);
10890+ lower_dentry =
10891+ lookup_one_len(name, lower_dir_dentry,
10892+ cursor->namelen +
10893+ UNIONFS_WHLEN);
10894+ if (IS_ERR(lower_dentry)) {
10895+ err = PTR_ERR(lower_dentry);
10896+ break;
10897+ }
10898+ if (lower_dentry->d_inode)
10899+ err = vfs_unlink(lower_dir, lower_dentry);
10900+ dput(lower_dentry);
10901+ if (err)
10902+ break;
10903+ }
10904+ }
10905+
10906+ __putname(name);
10907+
10908+ /* After all of the removals, we should copy the attributes once. */
10909+ fsstack_copy_attr_times(dentry->d_inode, lower_dir_dentry->d_inode);
10910+
10911+out:
10912+ return err;
10913+}
10914+
10915+
10916+void __delete_whiteouts(struct work_struct *work)
10917+{
10918+ struct sioq_args *args = container_of(work, struct sioq_args, work);
10919+ struct deletewh_args *d = &args->deletewh;
10920+
10921+ args->err = do_delete_whiteouts(d->dentry, d->bindex, d->namelist);
10922+ complete(&args->comp);
10923+}
10924+
10925+/* delete whiteouts in a dir (for rmdir operation) using sioq if necessary */
10926+int delete_whiteouts(struct dentry *dentry, int bindex,
10927+ struct unionfs_dir_state *namelist)
10928+{
10929+ int err;
10930+ struct super_block *sb;
10931+ struct dentry *lower_dir_dentry;
10932+ struct inode *lower_dir;
10933+ struct sioq_args args;
10934+
10935+ sb = dentry->d_sb;
10936+
10937+ BUG_ON(!S_ISDIR(dentry->d_inode->i_mode));
10938+ BUG_ON(bindex < dbstart(dentry));
10939+ BUG_ON(bindex > dbend(dentry));
10940+ err = is_robranch_super(sb, bindex);
10941+ if (err)
10942+ goto out;
10943+
10944+ lower_dir_dentry = unionfs_lower_dentry_idx(dentry, bindex);
10945+ BUG_ON(!S_ISDIR(lower_dir_dentry->d_inode->i_mode));
10946+ lower_dir = lower_dir_dentry->d_inode;
10947+ BUG_ON(!S_ISDIR(lower_dir->i_mode));
10948+
10949+ if (!inode_permission(lower_dir, MAY_WRITE | MAY_EXEC)) {
10950+ err = do_delete_whiteouts(dentry, bindex, namelist);
10951+ } else {
10952+ args.deletewh.namelist = namelist;
10953+ args.deletewh.dentry = dentry;
10954+ args.deletewh.bindex = bindex;
10955+ run_sioq(__delete_whiteouts, &args);
10956+ err = args.err;
10957+ }
10958+
10959+out:
10960+ return err;
10961+}
10962+
10963+/****************************************************************************
10964+ * Opaque directory helpers *
10965+ ****************************************************************************/
10966+
10967+/*
10968+ * is_opaque_dir: returns 0 if it is NOT an opaque dir, 1 if it is, and
10969+ * -errno if an error occurred trying to figure this out.
10970+ */
10971+int is_opaque_dir(struct dentry *dentry, int bindex)
10972+{
10973+ int err = 0;
10974+ struct dentry *lower_dentry;
10975+ struct dentry *wh_lower_dentry;
10976+ struct inode *lower_inode;
10977+ struct sioq_args args;
10978+
10979+ lower_dentry = unionfs_lower_dentry_idx(dentry, bindex);
10980+ lower_inode = lower_dentry->d_inode;
10981+
10982+ BUG_ON(!S_ISDIR(lower_inode->i_mode));
10983+
10984+ mutex_lock(&lower_inode->i_mutex);
10985+
10986+ if (!inode_permission(lower_inode, MAY_EXEC)) {
10987+ wh_lower_dentry =
10988+ lookup_one_len(UNIONFS_DIR_OPAQUE, lower_dentry,
10989+ sizeof(UNIONFS_DIR_OPAQUE) - 1);
10990+ } else {
10991+ args.is_opaque.dentry = lower_dentry;
10992+ run_sioq(__is_opaque_dir, &args);
10993+ wh_lower_dentry = args.ret;
10994+ }
10995+
10996+ mutex_unlock(&lower_inode->i_mutex);
10997+
10998+ if (IS_ERR(wh_lower_dentry)) {
10999+ err = PTR_ERR(wh_lower_dentry);
11000+ goto out;
11001+ }
11002+
11003+ /* This is an opaque dir iff wh_lower_dentry is positive */
11004+ err = !!wh_lower_dentry->d_inode;
11005+
11006+ dput(wh_lower_dentry);
11007+out:
11008+ return err;
11009+}
11010+
11011+void __is_opaque_dir(struct work_struct *work)
11012+{
11013+ struct sioq_args *args = container_of(work, struct sioq_args, work);
11014+
11015+ args->ret = lookup_one_len(UNIONFS_DIR_OPAQUE, args->is_opaque.dentry,
11016+ sizeof(UNIONFS_DIR_OPAQUE) - 1);
11017+ complete(&args->comp);
11018+}
11019+
11020+int make_dir_opaque(struct dentry *dentry, int bindex)
11021+{
11022+ int err = 0;
11023+ struct dentry *lower_dentry, *diropq;
11024+ struct inode *lower_dir;
11025+ struct nameidata nd;
11026+ kernel_cap_t orig_cap;
11027+
11028+ /*
11029+ * Opaque directory whiteout markers are special files (like regular
11030+ * whiteouts), and should appear to the users as if they don't
11031+ * exist. They should be created/deleted regardless of directory
11032+ * search/create permissions, but only for the duration of this
11033+ * creation of the .wh.__dir_opaque: file. Note, this does not
11034+ * circumvent normal ->permission).
11035+ */
11036+ orig_cap = current->cap_effective;
11037+ cap_raise(current->cap_effective, CAP_DAC_READ_SEARCH);
11038+ cap_raise(current->cap_effective, CAP_DAC_OVERRIDE);
11039+
11040+ lower_dentry = unionfs_lower_dentry_idx(dentry, bindex);
11041+ lower_dir = lower_dentry->d_inode;
11042+ BUG_ON(!S_ISDIR(dentry->d_inode->i_mode) ||
11043+ !S_ISDIR(lower_dir->i_mode));
11044+
11045+ mutex_lock(&lower_dir->i_mutex);
11046+ diropq = lookup_one_len(UNIONFS_DIR_OPAQUE, lower_dentry,
11047+ sizeof(UNIONFS_DIR_OPAQUE) - 1);
11048+ if (IS_ERR(diropq)) {
11049+ err = PTR_ERR(diropq);
11050+ goto out;
11051+ }
11052+
11053+ err = init_lower_nd(&nd, LOOKUP_CREATE);
11054+ if (unlikely(err < 0))
11055+ goto out;
11056+ if (!diropq->d_inode)
11057+ err = vfs_create(lower_dir, diropq, S_IRUGO, &nd);
11058+ if (!err)
11059+ dbopaque(dentry) = bindex;
11060+ release_lower_nd(&nd, err);
11061+
11062+ dput(diropq);
11063+
11064+out:
11065+ mutex_unlock(&lower_dir->i_mutex);
11066+ current->cap_effective = orig_cap;
11067+ return err;
11068+}
11069diff --git a/fs/unionfs/xattr.c b/fs/unionfs/xattr.c
11070new file mode 100644
11071index 0000000..93a8fce
11072--- /dev/null
11073+++ b/fs/unionfs/xattr.c
11074@@ -0,0 +1,153 @@
11075+/*
11076+ * Copyright (c) 2003-2008 Erez Zadok
11077+ * Copyright (c) 2003-2006 Charles P. Wright
11078+ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
11079+ * Copyright (c) 2005-2006 Junjiro Okajima
11080+ * Copyright (c) 2005 Arun M. Krishnakumar
11081+ * Copyright (c) 2004-2006 David P. Quigley
11082+ * Copyright (c) 2003-2004 Mohammad Nayyer Zubair
11083+ * Copyright (c) 2003 Puja Gupta
11084+ * Copyright (c) 2003 Harikesavan Krishnan
11085+ * Copyright (c) 2003-2008 Stony Brook University
11086+ * Copyright (c) 2003-2008 The Research Foundation of SUNY
11087+ *
11088+ * This program is free software; you can redistribute it and/or modify
11089+ * it under the terms of the GNU General Public License version 2 as
11090+ * published by the Free Software Foundation.
11091+ */
11092+
11093+#include "union.h"
11094+
11095+/* This is lifted from fs/xattr.c */
11096+void *unionfs_xattr_alloc(size_t size, size_t limit)
11097+{
11098+ void *ptr;
11099+
11100+ if (size > limit)
11101+ return ERR_PTR(-E2BIG);
11102+
11103+ if (!size) /* size request, no buffer is needed */
11104+ return NULL;
11105+
11106+ ptr = kmalloc(size, GFP_KERNEL);
11107+ if (unlikely(!ptr))
11108+ return ERR_PTR(-ENOMEM);
11109+ return ptr;
11110+}
11111+
11112+/*
11113+ * BKL held by caller.
11114+ * dentry->d_inode->i_mutex locked
11115+ */
11116+ssize_t unionfs_getxattr(struct dentry *dentry, const char *name, void *value,
11117+ size_t size)
11118+{
11119+ struct dentry *lower_dentry = NULL;
11120+ int err = -EOPNOTSUPP;
11121+
11122+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD);
11123+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
11124+
11125+ if (unlikely(!__unionfs_d_revalidate_chain(dentry, NULL, false))) {
11126+ err = -ESTALE;
11127+ goto out;
11128+ }
11129+
11130+ lower_dentry = unionfs_lower_dentry(dentry);
11131+
11132+ err = vfs_getxattr(lower_dentry, (char *) name, value, size);
11133+
11134+out:
11135+ unionfs_check_dentry(dentry);
11136+ unionfs_unlock_dentry(dentry);
11137+ unionfs_read_unlock(dentry->d_sb);
11138+ return err;
11139+}
11140+
11141+/*
11142+ * BKL held by caller.
11143+ * dentry->d_inode->i_mutex locked
11144+ */
11145+int unionfs_setxattr(struct dentry *dentry, const char *name,
11146+ const void *value, size_t size, int flags)
11147+{
11148+ struct dentry *lower_dentry = NULL;
11149+ int err = -EOPNOTSUPP;
11150+
11151+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD);
11152+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
11153+
11154+ if (unlikely(!__unionfs_d_revalidate_chain(dentry, NULL, false))) {
11155+ err = -ESTALE;
11156+ goto out;
11157+ }
11158+
11159+ lower_dentry = unionfs_lower_dentry(dentry);
11160+
11161+ err = vfs_setxattr(lower_dentry, (char *) name, (void *) value,
11162+ size, flags);
11163+
11164+out:
11165+ unionfs_check_dentry(dentry);
11166+ unionfs_unlock_dentry(dentry);
11167+ unionfs_read_unlock(dentry->d_sb);
11168+ return err;
11169+}
11170+
11171+/*
11172+ * BKL held by caller.
11173+ * dentry->d_inode->i_mutex locked
11174+ */
11175+int unionfs_removexattr(struct dentry *dentry, const char *name)
11176+{
11177+ struct dentry *lower_dentry = NULL;
11178+ int err = -EOPNOTSUPP;
11179+
11180+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD);
11181+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
11182+
11183+ if (unlikely(!__unionfs_d_revalidate_chain(dentry, NULL, false))) {
11184+ err = -ESTALE;
11185+ goto out;
11186+ }
11187+
11188+ lower_dentry = unionfs_lower_dentry(dentry);
11189+
11190+ err = vfs_removexattr(lower_dentry, (char *) name);
11191+
11192+out:
11193+ unionfs_check_dentry(dentry);
11194+ unionfs_unlock_dentry(dentry);
11195+ unionfs_read_unlock(dentry->d_sb);
11196+ return err;
11197+}
11198+
11199+/*
11200+ * BKL held by caller.
11201+ * dentry->d_inode->i_mutex locked
11202+ */
11203+ssize_t unionfs_listxattr(struct dentry *dentry, char *list, size_t size)
11204+{
11205+ struct dentry *lower_dentry = NULL;
11206+ int err = -EOPNOTSUPP;
11207+ char *encoded_list = NULL;
11208+
11209+ unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD);
11210+ unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);
11211+
11212+ if (unlikely(!__unionfs_d_revalidate_chain(dentry, NULL, false))) {
11213+ err = -ESTALE;
11214+ goto out;
11215+ }
11216+
11217+ lower_dentry = unionfs_lower_dentry(dentry);
11218+
11219+ encoded_list = list;
11220+ err = vfs_listxattr(lower_dentry, encoded_list, size);
11221+
11222+out:
11223+ unionfs_check_dentry(dentry);
11224+ unionfs_unlock_dentry(dentry);
11225+ unionfs_read_unlock(dentry->d_sb);
11226+ return err;
11227+}
11228diff --git a/include/linux/fs_stack.h b/include/linux/fs_stack.h
11229index bb516ce..6615a52 100644
11230--- a/include/linux/fs_stack.h
11231+++ b/include/linux/fs_stack.h
11232@@ -1,17 +1,27 @@
11233+/*
11234+ * Copyright (c) 2006-2007 Erez Zadok
11235+ * Copyright (c) 2006-2007 Josef 'Jeff' Sipek
11236+ * Copyright (c) 2006-2007 Stony Brook University
11237+ * Copyright (c) 2006-2007 The Research Foundation of SUNY
11238+ *
11239+ * This program is free software; you can redistribute it and/or modify
11240+ * it under the terms of the GNU General Public License version 2 as
11241+ * published by the Free Software Foundation.
11242+ */
11243+
11244 #ifndef _LINUX_FS_STACK_H
11245 #define _LINUX_FS_STACK_H
11246
11247-/* This file defines generic functions used primarily by stackable
11248+/*
11249+ * This file defines generic functions used primarily by stackable
11250 * filesystems; none of these functions require i_mutex to be held.
11251 */
11252
11253 #include <linux/fs.h>
11254
11255 /* externs for fs/stack.c */
11256-extern void fsstack_copy_attr_all(struct inode *dest, const struct inode *src,
11257- int (*get_nlinks)(struct inode *));
11258-
11259-extern void fsstack_copy_inode_size(struct inode *dst, const struct inode *src);
11260+extern void fsstack_copy_attr_all(struct inode *dest, const struct inode *src);
11261+extern void fsstack_copy_inode_size(struct inode *dst, struct inode *src);
11262
11263 /* inlines */
11264 static inline void fsstack_copy_attr_atime(struct inode *dest,
11265diff --git a/include/linux/magic.h b/include/linux/magic.h
11266index 1fa0c2c..67043ed 100644
11267--- a/include/linux/magic.h
11268+++ b/include/linux/magic.h
11269@@ -35,6 +35,8 @@
11270 #define REISER2FS_SUPER_MAGIC_STRING "ReIsEr2Fs"
11271 #define REISER2FS_JR_SUPER_MAGIC_STRING "ReIsEr3Fs"
11272
11273+#define UNIONFS_SUPER_MAGIC 0xf15f083d
11274+
11275 #define SMB_SUPER_MAGIC 0x517B
11276 #define USBDEVICE_SUPER_MAGIC 0x9fa2
11277 #define CGROUP_SUPER_MAGIC 0x27e0eb
11278diff --git a/include/linux/splice.h b/include/linux/splice.h
11279index 528dcb9..4b5727c 100644
11280--- a/include/linux/splice.h
11281+++ b/include/linux/splice.h
11282@@ -70,5 +70,10 @@ extern ssize_t splice_to_pipe(struct pipe_inode_info *,
11283 struct splice_pipe_desc *);
11284 extern ssize_t splice_direct_to_actor(struct file *, struct splice_desc *,
11285 splice_direct_actor *);
11286+extern long vfs_splice_from(struct pipe_inode_info *pipe, struct file *out,
11287+ loff_t *ppos, size_t len, unsigned int flags);
11288+extern long vfs_splice_to(struct file *in, loff_t *ppos,
11289+ struct pipe_inode_info *pipe, size_t len,
11290+ unsigned int flags);
11291
11292 #endif
11293diff --git a/include/linux/union_fs.h b/include/linux/union_fs.h
11294new file mode 100644
11295index 0000000..bc15a16
11296--- /dev/null
11297+++ b/include/linux/union_fs.h
11298@@ -0,0 +1,22 @@
11299+/*
11300+ * Copyright (c) 2003-2008 Erez Zadok
11301+ * Copyright (c) 2005-2007 Josef 'Jeff' Sipek
11302+ * Copyright (c) 2003-2008 Stony Brook University
11303+ * Copyright (c) 2003-2008 The Research Foundation of SUNY
11304+ *
11305+ * This program is free software; you can redistribute it and/or modify
11306+ * it under the terms of the GNU General Public License version 2 as
11307+ * published by the Free Software Foundation.
11308+ */
11309+
11310+#ifndef _LINUX_UNION_FS_H
11311+#define _LINUX_UNION_FS_H
11312+
11313+/*
11314+ * DEFINITIONS FOR USER AND KERNEL CODE:
11315+ */
11316+# define UNIONFS_IOCTL_INCGEN _IOR(0x15, 11, int)
11317+# define UNIONFS_IOCTL_QUERYFILE _IOR(0x15, 15, int)
11318+
11319+#endif /* _LINUX_UNIONFS_H */
11320+
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27-rc1/0011_workaround_unidef_step.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc1/0011_workaround_unidef_step.patch
new file mode 100644
index 0000000000..a77ff3c62f
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc1/0011_workaround_unidef_step.patch
@@ -0,0 +1,10 @@
1--- linux.trees.git/include/linux/videodev2.h.org 2008-08-15 16:31:03.000000000 -0700
2+++ linux.trees.git/include/linux/videodev2.h 2008-08-15 16:31:11.000000000 -0700
3@@ -59,7 +59,6 @@
4 #include <linux/time.h> /* need struct timeval */
5 #include <linux/compiler.h> /* need __user */
6 #else
7-#define __user
8 #include <sys/time.h>
9 #endif
10 #include <linux/ioctl.h>
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27-rc1/0012_intelfb_945gme.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc1/0012_intelfb_945gme.patch
new file mode 100644
index 0000000000..15ebe56328
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc1/0012_intelfb_945gme.patch
@@ -0,0 +1,153 @@
1The following patch adds support for Intel's 945GME graphics chip to
2the intelfb driver. I have assumed that the 945GME is identical to the
3already-supported 945GM apart from its PCI IDs; this is based on a quick
4look at the X driver for these chips which seems to treat them
5identically.
6
7Signed-off-by: Phil Endecott <spam_from_intelfb@chezphil.org>
8
9---
10
11The 945GME is used in the ASUS Eee 901, and I coded this in the hope that
12I'd be able to use it to get a console at the native 1024x600 resolution
13which is not known to the BIOS. I realised too late that the intelfb
14driver does not support mode changing on laptops, so it won't be any
15use for me. But rather than throw it away I will post it here as
16essentially "untested"; maybe someone who knows more about this driver,
17and with more useful hardware to test on, can pick it up.
18
19diff --git a/Documentation/fb/intelfb.txt b/Documentation/fb/intelfb.txt
20index 27a3160..dd9e944 100644
21--- a/Documentation/fb/intelfb.txt
22+++ b/Documentation/fb/intelfb.txt
23@@ -14,6 +14,7 @@ graphics devices. These would include:
24 Intel 915GM
25 Intel 945G
26 Intel 945GM
27+ Intel 945GME
28 Intel 965G
29 Intel 965GM
30
31diff --git a/drivers/video/intelfb/intelfb.h b/drivers/video/intelfb/intelfb.h
32index 3325fbd..a50bea6 100644
33--- a/drivers/video/intelfb/intelfb.h
34+++ b/drivers/video/intelfb/intelfb.h
35@@ -12,9 +12,9 @@
36 #endif
37
38 /*** Version/name ***/
39-#define INTELFB_VERSION "0.9.5"
40+#define INTELFB_VERSION "0.9.6"
41 #define INTELFB_MODULE_NAME "intelfb"
42-#define SUPPORTED_CHIPSETS "830M/845G/852GM/855GM/865G/915G/915GM/945G/945GM/965G/965GM"
43+#define SUPPORTED_CHIPSETS "830M/845G/852GM/855GM/865G/915G/915GM/945G/945GM/945GME/965G/965GM"
44
45
46 /*** Debug/feature defines ***/
47@@ -58,6 +58,7 @@
48 #define PCI_DEVICE_ID_INTEL_915GM 0x2592
49 #define PCI_DEVICE_ID_INTEL_945G 0x2772
50 #define PCI_DEVICE_ID_INTEL_945GM 0x27A2
51+#define PCI_DEVICE_ID_INTEL_945GME 0x27AE
52 #define PCI_DEVICE_ID_INTEL_965G 0x29A2
53 #define PCI_DEVICE_ID_INTEL_965GM 0x2A02
54
55@@ -160,6 +161,7 @@ enum intel_chips {
56 INTEL_915GM,
57 INTEL_945G,
58 INTEL_945GM,
59+ INTEL_945GME,
60 INTEL_965G,
61 INTEL_965GM,
62 };
63@@ -363,6 +365,7 @@ struct intelfb_info {
64 ((dinfo)->chipset == INTEL_915GM) || \
65 ((dinfo)->chipset == INTEL_945G) || \
66 ((dinfo)->chipset == INTEL_945GM) || \
67+ ((dinfo)->chipset == INTEL_945GME) || \
68 ((dinfo)->chipset == INTEL_965G) || \
69 ((dinfo)->chipset == INTEL_965GM))
70
71diff --git a/drivers/video/intelfb/intelfb_i2c.c b/drivers/video/intelfb/intelfb_i2c.c
72index fcf9fad..5d896b8 100644
73--- a/drivers/video/intelfb/intelfb_i2c.c
74+++ b/drivers/video/intelfb/intelfb_i2c.c
75@@ -171,6 +171,7 @@ void intelfb_create_i2c_busses(struct intelfb_info *dinfo)
76 /* has some LVDS + tv-out */
77 case INTEL_945G:
78 case INTEL_945GM:
79+ case INTEL_945GME:
80 case INTEL_965G:
81 case INTEL_965GM:
82 /* SDVO ports have a single control bus - 2 devices */
83diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c
84index e44303f..a09e236 100644
85--- a/drivers/video/intelfb/intelfbdrv.c
86+++ b/drivers/video/intelfb/intelfbdrv.c
87@@ -2,7 +2,7 @@
88 * intelfb
89 *
90 * Linux framebuffer driver for Intel(R) 830M/845G/852GM/855GM/865G/915G/915GM/
91- * 945G/945GM/965G/965GM integrated graphics chips.
92+ * 945G/945GM/945GME/965G/965GM integrated graphics chips.
93 *
94 * Copyright © 2002, 2003 David Dawes <dawes@xfree86.org>
95 * 2004 Sylvain Meyer
96@@ -102,6 +102,9 @@
97 *
98 * 04/2008 - Version 0.9.5
99 * Add support for 965G/965GM. (Maik Broemme <mbroemme@plusserver.de>)
100+ *
101+ * 08/2008 - Version 0.9.6
102+ * Add support for 945GME. (Phil Endecott <spam_from_intelfb@chezphil.org>)
103 */
104
105 #include <linux/module.h>
106@@ -183,6 +186,7 @@ static struct pci_device_id intelfb_pci_table[] __devinitdata = {
107 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_915GM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_915GM },
108 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_945G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_945G },
109 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_945GM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_945GM },
110+ { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_945GME, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_945GME },
111 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_965G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_965G },
112 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_965GM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_965GM },
113 { 0, }
114@@ -555,6 +559,7 @@ static int __devinit intelfb_pci_register(struct pci_dev *pdev,
115 (ent->device == PCI_DEVICE_ID_INTEL_915GM) ||
116 (ent->device == PCI_DEVICE_ID_INTEL_945G) ||
117 (ent->device == PCI_DEVICE_ID_INTEL_945GM) ||
118+ (ent->device == PCI_DEVICE_ID_INTEL_945GME) ||
119 (ent->device == PCI_DEVICE_ID_INTEL_965G) ||
120 (ent->device == PCI_DEVICE_ID_INTEL_965GM)) {
121
122diff --git a/drivers/video/intelfb/intelfbhw.c b/drivers/video/intelfb/intelfbhw.c
123index 8e6d6a4..8b26b27 100644
124--- a/drivers/video/intelfb/intelfbhw.c
125+++ b/drivers/video/intelfb/intelfbhw.c
126@@ -143,6 +143,12 @@ int intelfbhw_get_chipset(struct pci_dev *pdev, struct intelfb_info *dinfo)
127 dinfo->mobile = 1;
128 dinfo->pll_index = PLLS_I9xx;
129 return 0;
130+ case PCI_DEVICE_ID_INTEL_945GME:
131+ dinfo->name = "Intel(R) 945GME";
132+ dinfo->chipset = INTEL_945GME;
133+ dinfo->mobile = 1;
134+ dinfo->pll_index = PLLS_I9xx;
135+ return 0;
136 case PCI_DEVICE_ID_INTEL_965G:
137 dinfo->name = "Intel(R) 965G";
138 dinfo->chipset = INTEL_965G;
139@@ -186,6 +192,7 @@ int intelfbhw_get_memory(struct pci_dev *pdev, int *aperture_size,
140 case PCI_DEVICE_ID_INTEL_915GM:
141 case PCI_DEVICE_ID_INTEL_945G:
142 case PCI_DEVICE_ID_INTEL_945GM:
143+ case PCI_DEVICE_ID_INTEL_945GME:
144 case PCI_DEVICE_ID_INTEL_965G:
145 case PCI_DEVICE_ID_INTEL_965GM:
146 /* 915, 945 and 965 chipsets support a 256MB aperture.
147
148
149--
150To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
151the body of a message to majordomo@vger.kernel.org
152More majordomo info at http://vger.kernel.org/majordomo-info.html
153Please read the FAQ at http://www.tux.org/lkml/ \ No newline at end of file
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27-rc1/defconfig-eee901 b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc1/defconfig-eee901
new file mode 100644
index 0000000000..9820821a7b
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc1/defconfig-eee901
@@ -0,0 +1,2419 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.27-rc1
4# Wed Oct 1 17:20:02 2008
5#
6# CONFIG_64BIT is not set
7CONFIG_X86_32=y
8# CONFIG_X86_64 is not set
9CONFIG_X86=y
10CONFIG_ARCH_DEFCONFIG="arch/x86/configs/i386_defconfig"
11# CONFIG_GENERIC_LOCKBREAK is not set
12CONFIG_GENERIC_TIME=y
13CONFIG_GENERIC_CMOS_UPDATE=y
14CONFIG_CLOCKSOURCE_WATCHDOG=y
15CONFIG_GENERIC_CLOCKEVENTS=y
16CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
17CONFIG_LOCKDEP_SUPPORT=y
18CONFIG_STACKTRACE_SUPPORT=y
19CONFIG_HAVE_LATENCYTOP_SUPPORT=y
20CONFIG_FAST_CMPXCHG_LOCAL=y
21CONFIG_MMU=y
22CONFIG_ZONE_DMA=y
23CONFIG_GENERIC_ISA_DMA=y
24CONFIG_GENERIC_IOMAP=y
25CONFIG_GENERIC_BUG=y
26CONFIG_GENERIC_HWEIGHT=y
27# CONFIG_GENERIC_GPIO is not set
28CONFIG_ARCH_MAY_HAVE_PC_FDC=y
29# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
30CONFIG_RWSEM_XCHGADD_ALGORITHM=y
31# CONFIG_ARCH_HAS_ILOG2_U32 is not set
32# CONFIG_ARCH_HAS_ILOG2_U64 is not set
33CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
34CONFIG_GENERIC_CALIBRATE_DELAY=y
35# CONFIG_GENERIC_TIME_VSYSCALL is not set
36CONFIG_ARCH_HAS_CPU_RELAX=y
37CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y
38CONFIG_HAVE_SETUP_PER_CPU_AREA=y
39# CONFIG_HAVE_CPUMASK_OF_CPU_MAP is not set
40CONFIG_ARCH_HIBERNATION_POSSIBLE=y
41CONFIG_ARCH_SUSPEND_POSSIBLE=y
42# CONFIG_ZONE_DMA32 is not set
43CONFIG_ARCH_POPULATES_NODE_MAP=y
44# CONFIG_AUDIT_ARCH is not set
45CONFIG_ARCH_SUPPORTS_AOUT=y
46CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING=y
47CONFIG_GENERIC_HARDIRQS=y
48CONFIG_GENERIC_IRQ_PROBE=y
49CONFIG_GENERIC_PENDING_IRQ=y
50CONFIG_X86_SMP=y
51CONFIG_X86_32_SMP=y
52CONFIG_X86_HT=y
53CONFIG_X86_BIOS_REBOOT=y
54CONFIG_X86_TRAMPOLINE=y
55CONFIG_KTIME_SCALAR=y
56CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
57
58#
59# General setup
60#
61CONFIG_EXPERIMENTAL=y
62CONFIG_LOCK_KERNEL=y
63CONFIG_INIT_ENV_ARG_LIMIT=32
64CONFIG_LOCALVERSION="-eee901"
65# CONFIG_LOCALVERSION_AUTO is not set
66CONFIG_SWAP=y
67CONFIG_SYSVIPC=y
68CONFIG_SYSVIPC_SYSCTL=y
69CONFIG_POSIX_MQUEUE=y
70CONFIG_BSD_PROCESS_ACCT=y
71CONFIG_BSD_PROCESS_ACCT_V3=y
72CONFIG_TASKSTATS=y
73CONFIG_TASK_DELAY_ACCT=y
74CONFIG_TASK_XACCT=y
75CONFIG_TASK_IO_ACCOUNTING=y
76CONFIG_AUDIT=y
77CONFIG_AUDITSYSCALL=y
78CONFIG_AUDIT_TREE=y
79CONFIG_IKCONFIG=y
80CONFIG_IKCONFIG_PROC=y
81CONFIG_LOG_BUF_SHIFT=17
82# CONFIG_CGROUPS is not set
83CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y
84# CONFIG_GROUP_SCHED is not set
85# CONFIG_SYSFS_DEPRECATED_V2 is not set
86CONFIG_RELAY=y
87CONFIG_NAMESPACES=y
88# CONFIG_UTS_NS is not set
89# CONFIG_IPC_NS is not set
90CONFIG_USER_NS=y
91# CONFIG_PID_NS is not set
92CONFIG_BLK_DEV_INITRD=y
93CONFIG_INITRAMFS_SOURCE=""
94CONFIG_CC_OPTIMIZE_FOR_SIZE=y
95CONFIG_SYSCTL=y
96# CONFIG_EMBEDDED is not set
97CONFIG_UID16=y
98CONFIG_SYSCTL_SYSCALL=y
99CONFIG_SYSCTL_SYSCALL_CHECK=y
100CONFIG_KALLSYMS=y
101CONFIG_KALLSYMS_ALL=y
102CONFIG_KALLSYMS_EXTRA_PASS=y
103CONFIG_HOTPLUG=y
104CONFIG_PRINTK=y
105CONFIG_BUG=y
106CONFIG_ELF_CORE=y
107CONFIG_PCSPKR_PLATFORM=y
108# CONFIG_COMPAT_BRK is not set
109CONFIG_BASE_FULL=y
110CONFIG_FUTEX=y
111CONFIG_ANON_INODES=y
112CONFIG_EPOLL=y
113CONFIG_SIGNALFD=y
114CONFIG_TIMERFD=y
115CONFIG_EVENTFD=y
116CONFIG_SHMEM=y
117CONFIG_VM_EVENT_COUNTERS=y
118CONFIG_SLAB=y
119# CONFIG_SLUB is not set
120# CONFIG_SLOB is not set
121CONFIG_PROFILING=y
122# CONFIG_MARKERS is not set
123# CONFIG_OPROFILE is not set
124CONFIG_HAVE_OPROFILE=y
125# CONFIG_KPROBES is not set
126CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
127CONFIG_HAVE_IOREMAP_PROT=y
128CONFIG_HAVE_KPROBES=y
129CONFIG_HAVE_KRETPROBES=y
130# CONFIG_HAVE_ARCH_TRACEHOOK is not set
131# CONFIG_HAVE_DMA_ATTRS is not set
132CONFIG_USE_GENERIC_SMP_HELPERS=y
133# CONFIG_HAVE_CLK is not set
134CONFIG_PROC_PAGE_MONITOR=y
135CONFIG_HAVE_GENERIC_DMA_COHERENT=y
136CONFIG_SLABINFO=y
137CONFIG_RT_MUTEXES=y
138# CONFIG_TINY_SHMEM is not set
139CONFIG_BASE_SMALL=0
140CONFIG_MODULES=y
141# CONFIG_MODULE_FORCE_LOAD is not set
142CONFIG_MODULE_UNLOAD=y
143# CONFIG_MODULE_FORCE_UNLOAD is not set
144# CONFIG_MODVERSIONS is not set
145# CONFIG_MODULE_SRCVERSION_ALL is not set
146CONFIG_KMOD=y
147CONFIG_STOP_MACHINE=y
148CONFIG_BLOCK=y
149# CONFIG_LBD is not set
150CONFIG_BLK_DEV_IO_TRACE=y
151# CONFIG_LSF is not set
152CONFIG_BLK_DEV_BSG=y
153# CONFIG_BLK_DEV_INTEGRITY is not set
154
155#
156# IO Schedulers
157#
158CONFIG_IOSCHED_NOOP=y
159# CONFIG_IOSCHED_AS is not set
160# CONFIG_IOSCHED_DEADLINE is not set
161CONFIG_IOSCHED_CFQ=y
162# CONFIG_DEFAULT_AS is not set
163# CONFIG_DEFAULT_DEADLINE is not set
164CONFIG_DEFAULT_CFQ=y
165# CONFIG_DEFAULT_NOOP is not set
166CONFIG_DEFAULT_IOSCHED="cfq"
167CONFIG_CLASSIC_RCU=y
168
169#
170# Processor type and features
171#
172CONFIG_TICK_ONESHOT=y
173CONFIG_NO_HZ=y
174CONFIG_HIGH_RES_TIMERS=y
175CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
176CONFIG_SMP=y
177CONFIG_X86_FIND_SMP_CONFIG=y
178CONFIG_X86_MPPARSE=y
179CONFIG_X86_PC=y
180# CONFIG_X86_ELAN is not set
181# CONFIG_X86_VOYAGER is not set
182# CONFIG_X86_GENERICARCH is not set
183# CONFIG_X86_VSMP is not set
184# CONFIG_X86_RDC321X is not set
185CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
186# CONFIG_PARAVIRT_GUEST is not set
187# CONFIG_MEMTEST is not set
188# CONFIG_M386 is not set
189# CONFIG_M486 is not set
190# CONFIG_M586 is not set
191# CONFIG_M586TSC is not set
192# CONFIG_M586MMX is not set
193CONFIG_M686=y
194# CONFIG_MPENTIUMII is not set
195# CONFIG_MPENTIUMIII is not set
196# CONFIG_MPENTIUMM is not set
197# CONFIG_MPENTIUM4 is not set
198# CONFIG_MK6 is not set
199# CONFIG_MK7 is not set
200# CONFIG_MK8 is not set
201# CONFIG_MCRUSOE is not set
202# CONFIG_MEFFICEON is not set
203# CONFIG_MWINCHIPC6 is not set
204# CONFIG_MWINCHIP2 is not set
205# CONFIG_MWINCHIP3D is not set
206# CONFIG_MGEODEGX1 is not set
207# CONFIG_MGEODE_LX is not set
208# CONFIG_MCYRIXIII is not set
209# CONFIG_MVIAC3_2 is not set
210# CONFIG_MVIAC7 is not set
211# CONFIG_MPSC is not set
212# CONFIG_MCORE2 is not set
213# CONFIG_GENERIC_CPU is not set
214# CONFIG_X86_GENERIC is not set
215CONFIG_X86_CPU=y
216CONFIG_X86_CMPXCHG=y
217CONFIG_X86_L1_CACHE_SHIFT=5
218CONFIG_X86_XADD=y
219# CONFIG_X86_PPRO_FENCE is not set
220CONFIG_X86_WP_WORKS_OK=y
221CONFIG_X86_INVLPG=y
222CONFIG_X86_BSWAP=y
223CONFIG_X86_POPAD_OK=y
224CONFIG_X86_USE_PPRO_CHECKSUM=y
225CONFIG_X86_P6_NOP=y
226CONFIG_X86_TSC=y
227CONFIG_X86_CMOV=y
228CONFIG_X86_MINIMUM_CPU_FAMILY=6
229CONFIG_X86_DEBUGCTLMSR=y
230CONFIG_HPET_TIMER=y
231CONFIG_HPET_EMULATE_RTC=y
232CONFIG_DMI=y
233# CONFIG_IOMMU_HELPER is not set
234CONFIG_NR_CPUS=2
235CONFIG_SCHED_SMT=y
236CONFIG_SCHED_MC=y
237# CONFIG_PREEMPT_NONE is not set
238CONFIG_PREEMPT_VOLUNTARY=y
239# CONFIG_PREEMPT is not set
240CONFIG_X86_LOCAL_APIC=y
241CONFIG_X86_IO_APIC=y
242CONFIG_X86_MCE=y
243# CONFIG_X86_MCE_NONFATAL is not set
244# CONFIG_X86_MCE_P4THERMAL is not set
245CONFIG_VM86=y
246# CONFIG_TOSHIBA is not set
247# CONFIG_I8K is not set
248# CONFIG_X86_REBOOTFIXUPS is not set
249CONFIG_MICROCODE=y
250CONFIG_MICROCODE_OLD_INTERFACE=y
251CONFIG_X86_MSR=y
252CONFIG_X86_CPUID=y
253# CONFIG_NOHIGHMEM is not set
254CONFIG_HIGHMEM4G=y
255# CONFIG_HIGHMEM64G is not set
256CONFIG_PAGE_OFFSET=0xC0000000
257CONFIG_HIGHMEM=y
258CONFIG_NEED_NODE_MEMMAP_SIZE=y
259CONFIG_ARCH_FLATMEM_ENABLE=y
260CONFIG_ARCH_SPARSEMEM_ENABLE=y
261CONFIG_ARCH_SELECT_MEMORY_MODEL=y
262CONFIG_SELECT_MEMORY_MODEL=y
263# CONFIG_FLATMEM_MANUAL is not set
264# CONFIG_DISCONTIGMEM_MANUAL is not set
265CONFIG_SPARSEMEM_MANUAL=y
266CONFIG_SPARSEMEM=y
267CONFIG_HAVE_GET_USER_PAGES_FAST=y
268CONFIG_HAVE_MEMORY_PRESENT=y
269CONFIG_SPARSEMEM_STATIC=y
270# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
271
272#
273# Memory hotplug is currently incompatible with Software Suspend
274#
275CONFIG_PAGEFLAGS_EXTENDED=y
276CONFIG_SPLIT_PTLOCK_CPUS=4
277CONFIG_RESOURCES_64BIT=y
278CONFIG_ZONE_DMA_FLAG=1
279CONFIG_BOUNCE=y
280CONFIG_VIRT_TO_BUS=y
281# CONFIG_HIGHPTE is not set
282# CONFIG_MATH_EMULATION is not set
283CONFIG_MTRR=y
284# CONFIG_MTRR_SANITIZER is not set
285# CONFIG_X86_PAT is not set
286# CONFIG_EFI is not set
287# CONFIG_IRQBALANCE is not set
288# CONFIG_SECCOMP is not set
289# CONFIG_HZ_100 is not set
290# CONFIG_HZ_250 is not set
291# CONFIG_HZ_300 is not set
292CONFIG_HZ_1000=y
293CONFIG_HZ=1000
294CONFIG_SCHED_HRTICK=y
295CONFIG_KEXEC=y
296CONFIG_CRASH_DUMP=y
297# CONFIG_KEXEC_JUMP is not set
298CONFIG_PHYSICAL_START=0x400000
299CONFIG_RELOCATABLE=y
300CONFIG_PHYSICAL_ALIGN=0x200000
301CONFIG_HOTPLUG_CPU=y
302CONFIG_COMPAT_VDSO=y
303CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
304
305#
306# Power management options
307#
308CONFIG_PM=y
309CONFIG_PM_DEBUG=y
310# CONFIG_PM_VERBOSE is not set
311CONFIG_CAN_PM_TRACE=y
312CONFIG_PM_TRACE=y
313CONFIG_PM_TRACE_RTC=y
314CONFIG_PM_SLEEP_SMP=y
315CONFIG_PM_SLEEP=y
316CONFIG_SUSPEND=y
317# CONFIG_PM_TEST_SUSPEND is not set
318CONFIG_SUSPEND_FREEZER=y
319CONFIG_HIBERNATION=y
320CONFIG_PM_STD_PARTITION=""
321CONFIG_ACPI=y
322CONFIG_ACPI_SLEEP=y
323CONFIG_ACPI_PROCFS=y
324CONFIG_ACPI_PROCFS_POWER=y
325CONFIG_ACPI_SYSFS_POWER=y
326CONFIG_ACPI_PROC_EVENT=y
327CONFIG_ACPI_AC=y
328CONFIG_ACPI_BATTERY=m
329CONFIG_ACPI_BUTTON=y
330CONFIG_ACPI_VIDEO=y
331CONFIG_ACPI_FAN=y
332CONFIG_ACPI_DOCK=y
333# CONFIG_ACPI_BAY is not set
334CONFIG_ACPI_PROCESSOR=y
335CONFIG_ACPI_HOTPLUG_CPU=y
336CONFIG_ACPI_THERMAL=y
337CONFIG_ACPI_WMI=m
338CONFIG_ACPI_ASUS=y
339# CONFIG_ACPI_TOSHIBA is not set
340# CONFIG_ACPI_CUSTOM_DSDT is not set
341CONFIG_ACPI_BLACKLIST_YEAR=0
342# CONFIG_ACPI_DEBUG is not set
343CONFIG_ACPI_EC=y
344# CONFIG_ACPI_PCI_SLOT is not set
345CONFIG_ACPI_POWER=y
346CONFIG_ACPI_SYSTEM=y
347CONFIG_X86_PM_TIMER=y
348CONFIG_ACPI_CONTAINER=y
349CONFIG_ACPI_SBS=m
350# CONFIG_APM is not set
351
352#
353# CPU Frequency scaling
354#
355CONFIG_CPU_FREQ=y
356CONFIG_CPU_FREQ_TABLE=y
357CONFIG_CPU_FREQ_DEBUG=y
358CONFIG_CPU_FREQ_STAT=m
359CONFIG_CPU_FREQ_STAT_DETAILS=y
360CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
361# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
362# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
363# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
364# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
365CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
366# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
367CONFIG_CPU_FREQ_GOV_USERSPACE=y
368CONFIG_CPU_FREQ_GOV_ONDEMAND=y
369# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
370
371#
372# CPUFreq processor drivers
373#
374CONFIG_X86_ACPI_CPUFREQ=y
375# CONFIG_X86_POWERNOW_K6 is not set
376# CONFIG_X86_POWERNOW_K7 is not set
377# CONFIG_X86_POWERNOW_K8 is not set
378# CONFIG_X86_GX_SUSPMOD is not set
379# CONFIG_X86_SPEEDSTEP_CENTRINO is not set
380# CONFIG_X86_SPEEDSTEP_ICH is not set
381# CONFIG_X86_SPEEDSTEP_SMI is not set
382# CONFIG_X86_P4_CLOCKMOD is not set
383# CONFIG_X86_CPUFREQ_NFORCE2 is not set
384# CONFIG_X86_LONGRUN is not set
385# CONFIG_X86_LONGHAUL is not set
386# CONFIG_X86_E_POWERSAVER is not set
387
388#
389# shared options
390#
391# CONFIG_X86_ACPI_CPUFREQ_PROC_INTF is not set
392# CONFIG_X86_SPEEDSTEP_LIB is not set
393CONFIG_CPU_IDLE=y
394CONFIG_CPU_IDLE_GOV_LADDER=y
395CONFIG_CPU_IDLE_GOV_MENU=y
396
397#
398# Bus options (PCI etc.)
399#
400CONFIG_PCI=y
401# CONFIG_PCI_GOBIOS is not set
402# CONFIG_PCI_GOMMCONFIG is not set
403# CONFIG_PCI_GODIRECT is not set
404# CONFIG_PCI_GOOLPC is not set
405CONFIG_PCI_GOANY=y
406CONFIG_PCI_BIOS=y
407CONFIG_PCI_DIRECT=y
408CONFIG_PCI_MMCONFIG=y
409CONFIG_PCI_DOMAINS=y
410CONFIG_PCIEPORTBUS=y
411CONFIG_PCIEAER=y
412CONFIG_PCIEASPM=y
413# CONFIG_PCIEASPM_DEBUG is not set
414CONFIG_ARCH_SUPPORTS_MSI=y
415CONFIG_PCI_MSI=y
416CONFIG_PCI_LEGACY=y
417# CONFIG_PCI_DEBUG is not set
418CONFIG_HT_IRQ=y
419CONFIG_ISA_DMA_API=y
420# CONFIG_ISA is not set
421# CONFIG_MCA is not set
422# CONFIG_SCx200 is not set
423# CONFIG_OLPC is not set
424CONFIG_K8_NB=y
425# CONFIG_PCCARD is not set
426# CONFIG_HOTPLUG_PCI is not set
427
428#
429# Executable file formats / Emulations
430#
431CONFIG_BINFMT_ELF=y
432# CONFIG_BINFMT_AOUT is not set
433CONFIG_BINFMT_MISC=y
434
435#
436# Networking
437#
438CONFIG_NET=y
439
440#
441# Networking options
442#
443CONFIG_PACKET=y
444CONFIG_PACKET_MMAP=y
445CONFIG_UNIX=y
446CONFIG_XFRM=y
447CONFIG_XFRM_USER=y
448CONFIG_XFRM_SUB_POLICY=y
449CONFIG_XFRM_MIGRATE=y
450CONFIG_XFRM_STATISTICS=y
451CONFIG_XFRM_IPCOMP=m
452CONFIG_NET_KEY=m
453CONFIG_NET_KEY_MIGRATE=y
454CONFIG_INET=y
455CONFIG_IP_MULTICAST=y
456# CONFIG_IP_ADVANCED_ROUTER is not set
457CONFIG_IP_FIB_HASH=y
458# CONFIG_IP_PNP is not set
459# CONFIG_NET_IPIP is not set
460# CONFIG_NET_IPGRE is not set
461CONFIG_IP_MROUTE=y
462CONFIG_IP_PIMSM_V1=y
463CONFIG_IP_PIMSM_V2=y
464# CONFIG_ARPD is not set
465CONFIG_SYN_COOKIES=y
466CONFIG_INET_AH=m
467CONFIG_INET_ESP=m
468CONFIG_INET_IPCOMP=m
469CONFIG_INET_XFRM_TUNNEL=m
470CONFIG_INET_TUNNEL=m
471CONFIG_INET_XFRM_MODE_TRANSPORT=m
472CONFIG_INET_XFRM_MODE_TUNNEL=m
473CONFIG_INET_XFRM_MODE_BEET=m
474CONFIG_INET_LRO=y
475CONFIG_INET_DIAG=m
476CONFIG_INET_TCP_DIAG=m
477CONFIG_TCP_CONG_ADVANCED=y
478CONFIG_TCP_CONG_BIC=m
479CONFIG_TCP_CONG_CUBIC=y
480# CONFIG_TCP_CONG_WESTWOOD is not set
481# CONFIG_TCP_CONG_HTCP is not set
482# CONFIG_TCP_CONG_HSTCP is not set
483# CONFIG_TCP_CONG_HYBLA is not set
484# CONFIG_TCP_CONG_VEGAS is not set
485# CONFIG_TCP_CONG_SCALABLE is not set
486# CONFIG_TCP_CONG_LP is not set
487# CONFIG_TCP_CONG_VENO is not set
488# CONFIG_TCP_CONG_YEAH is not set
489# CONFIG_TCP_CONG_ILLINOIS is not set
490# CONFIG_DEFAULT_BIC is not set
491CONFIG_DEFAULT_CUBIC=y
492# CONFIG_DEFAULT_HTCP is not set
493# CONFIG_DEFAULT_VEGAS is not set
494# CONFIG_DEFAULT_WESTWOOD is not set
495# CONFIG_DEFAULT_RENO is not set
496CONFIG_DEFAULT_TCP_CONG="cubic"
497CONFIG_TCP_MD5SIG=y
498# CONFIG_IP_VS is not set
499CONFIG_IPV6=y
500CONFIG_IPV6_PRIVACY=y
501CONFIG_IPV6_ROUTER_PREF=y
502CONFIG_IPV6_ROUTE_INFO=y
503CONFIG_IPV6_OPTIMISTIC_DAD=y
504CONFIG_INET6_AH=m
505CONFIG_INET6_ESP=m
506CONFIG_INET6_IPCOMP=m
507CONFIG_IPV6_MIP6=m
508CONFIG_INET6_XFRM_TUNNEL=m
509CONFIG_INET6_TUNNEL=m
510CONFIG_INET6_XFRM_MODE_TRANSPORT=m
511CONFIG_INET6_XFRM_MODE_TUNNEL=m
512CONFIG_INET6_XFRM_MODE_BEET=m
513CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
514CONFIG_IPV6_SIT=m
515CONFIG_IPV6_NDISC_NODETYPE=y
516CONFIG_IPV6_TUNNEL=m
517CONFIG_IPV6_MULTIPLE_TABLES=y
518CONFIG_IPV6_SUBTREES=y
519# CONFIG_IPV6_MROUTE is not set
520CONFIG_NETLABEL=y
521CONFIG_NETWORK_SECMARK=y
522CONFIG_NETFILTER=y
523# CONFIG_NETFILTER_DEBUG is not set
524CONFIG_NETFILTER_ADVANCED=y
525
526#
527# Core Netfilter Configuration
528#
529CONFIG_NETFILTER_NETLINK=m
530CONFIG_NETFILTER_NETLINK_QUEUE=m
531CONFIG_NETFILTER_NETLINK_LOG=m
532CONFIG_NF_CONNTRACK=y
533CONFIG_NF_CT_ACCT=y
534CONFIG_NF_CONNTRACK_MARK=y
535CONFIG_NF_CONNTRACK_SECMARK=y
536CONFIG_NF_CONNTRACK_EVENTS=y
537# CONFIG_NF_CT_PROTO_DCCP is not set
538CONFIG_NF_CT_PROTO_GRE=m
539CONFIG_NF_CT_PROTO_SCTP=m
540CONFIG_NF_CT_PROTO_UDPLITE=m
541CONFIG_NF_CONNTRACK_AMANDA=m
542CONFIG_NF_CONNTRACK_FTP=m
543CONFIG_NF_CONNTRACK_H323=m
544CONFIG_NF_CONNTRACK_IRC=m
545CONFIG_NF_CONNTRACK_NETBIOS_NS=m
546CONFIG_NF_CONNTRACK_PPTP=m
547CONFIG_NF_CONNTRACK_SANE=m
548CONFIG_NF_CONNTRACK_SIP=m
549CONFIG_NF_CONNTRACK_TFTP=m
550CONFIG_NF_CT_NETLINK=m
551CONFIG_NETFILTER_XTABLES=y
552CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
553CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
554CONFIG_NETFILTER_XT_TARGET_DSCP=m
555CONFIG_NETFILTER_XT_TARGET_MARK=m
556CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
557CONFIG_NETFILTER_XT_TARGET_NFLOG=m
558CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
559CONFIG_NETFILTER_XT_TARGET_RATEEST=m
560CONFIG_NETFILTER_XT_TARGET_TRACE=m
561CONFIG_NETFILTER_XT_TARGET_SECMARK=m
562CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
563CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
564CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
565CONFIG_NETFILTER_XT_MATCH_COMMENT=m
566CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
567CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
568CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
569CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
570# CONFIG_NETFILTER_XT_MATCH_DCCP is not set
571CONFIG_NETFILTER_XT_MATCH_DSCP=m
572CONFIG_NETFILTER_XT_MATCH_ESP=m
573CONFIG_NETFILTER_XT_MATCH_HELPER=m
574CONFIG_NETFILTER_XT_MATCH_IPRANGE=m
575CONFIG_NETFILTER_XT_MATCH_LENGTH=m
576CONFIG_NETFILTER_XT_MATCH_LIMIT=m
577CONFIG_NETFILTER_XT_MATCH_MAC=m
578CONFIG_NETFILTER_XT_MATCH_MARK=m
579CONFIG_NETFILTER_XT_MATCH_OWNER=m
580CONFIG_NETFILTER_XT_MATCH_POLICY=m
581CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
582CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
583CONFIG_NETFILTER_XT_MATCH_QUOTA=m
584CONFIG_NETFILTER_XT_MATCH_RATEEST=m
585CONFIG_NETFILTER_XT_MATCH_REALM=m
586CONFIG_NETFILTER_XT_MATCH_SCTP=m
587CONFIG_NETFILTER_XT_MATCH_STATE=y
588CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
589CONFIG_NETFILTER_XT_MATCH_STRING=m
590CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
591CONFIG_NETFILTER_XT_MATCH_TIME=m
592CONFIG_NETFILTER_XT_MATCH_U32=m
593CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
594
595#
596# IP: Netfilter Configuration
597#
598CONFIG_NF_CONNTRACK_IPV4=y
599# CONFIG_NF_CONNTRACK_PROC_COMPAT is not set
600CONFIG_IP_NF_QUEUE=m
601CONFIG_IP_NF_IPTABLES=y
602CONFIG_IP_NF_MATCH_RECENT=m
603CONFIG_IP_NF_MATCH_ECN=m
604CONFIG_IP_NF_MATCH_AH=m
605CONFIG_IP_NF_MATCH_TTL=m
606CONFIG_IP_NF_MATCH_ADDRTYPE=m
607CONFIG_IP_NF_FILTER=y
608CONFIG_IP_NF_TARGET_REJECT=y
609CONFIG_IP_NF_TARGET_LOG=m
610CONFIG_IP_NF_TARGET_ULOG=m
611CONFIG_NF_NAT=m
612CONFIG_NF_NAT_NEEDED=y
613CONFIG_IP_NF_TARGET_MASQUERADE=m
614CONFIG_IP_NF_TARGET_REDIRECT=m
615CONFIG_IP_NF_TARGET_NETMAP=m
616CONFIG_NF_NAT_SNMP_BASIC=m
617CONFIG_NF_NAT_PROTO_GRE=m
618CONFIG_NF_NAT_PROTO_UDPLITE=m
619CONFIG_NF_NAT_PROTO_SCTP=m
620CONFIG_NF_NAT_FTP=m
621CONFIG_NF_NAT_IRC=m
622CONFIG_NF_NAT_TFTP=m
623CONFIG_NF_NAT_AMANDA=m
624CONFIG_NF_NAT_PPTP=m
625CONFIG_NF_NAT_H323=m
626CONFIG_NF_NAT_SIP=m
627CONFIG_IP_NF_MANGLE=m
628CONFIG_IP_NF_TARGET_ECN=m
629CONFIG_IP_NF_TARGET_TTL=m
630CONFIG_IP_NF_TARGET_CLUSTERIP=m
631CONFIG_IP_NF_RAW=m
632# CONFIG_IP_NF_SECURITY is not set
633CONFIG_IP_NF_ARPTABLES=m
634CONFIG_IP_NF_ARPFILTER=m
635CONFIG_IP_NF_ARP_MANGLE=m
636
637#
638# IPv6: Netfilter Configuration
639#
640CONFIG_NF_CONNTRACK_IPV6=y
641CONFIG_IP6_NF_QUEUE=m
642CONFIG_IP6_NF_IPTABLES=y
643CONFIG_IP6_NF_MATCH_RT=m
644CONFIG_IP6_NF_MATCH_OPTS=m
645CONFIG_IP6_NF_MATCH_FRAG=m
646CONFIG_IP6_NF_MATCH_HL=m
647CONFIG_IP6_NF_MATCH_IPV6HEADER=m
648CONFIG_IP6_NF_MATCH_AH=m
649CONFIG_IP6_NF_MATCH_MH=m
650CONFIG_IP6_NF_MATCH_EUI64=m
651CONFIG_IP6_NF_FILTER=y
652CONFIG_IP6_NF_TARGET_LOG=m
653CONFIG_IP6_NF_TARGET_REJECT=y
654CONFIG_IP6_NF_MANGLE=m
655CONFIG_IP6_NF_TARGET_HL=m
656CONFIG_IP6_NF_RAW=m
657# CONFIG_IP6_NF_SECURITY is not set
658# CONFIG_IP_DCCP is not set
659# CONFIG_IP_SCTP is not set
660# CONFIG_TIPC is not set
661# CONFIG_ATM is not set
662# CONFIG_BRIDGE is not set
663# CONFIG_VLAN_8021Q is not set
664# CONFIG_DECNET is not set
665# CONFIG_LLC2 is not set
666# CONFIG_IPX is not set
667# CONFIG_ATALK is not set
668# CONFIG_X25 is not set
669# CONFIG_LAPB is not set
670# CONFIG_ECONET is not set
671# CONFIG_WAN_ROUTER is not set
672# CONFIG_NET_SCHED is not set
673CONFIG_NET_CLS_ROUTE=y
674
675#
676# Network testing
677#
678# CONFIG_NET_PKTGEN is not set
679# CONFIG_HAMRADIO is not set
680# CONFIG_CAN is not set
681# CONFIG_IRDA is not set
682CONFIG_BT=m
683CONFIG_BT_L2CAP=m
684CONFIG_BT_SCO=m
685CONFIG_BT_RFCOMM=m
686CONFIG_BT_RFCOMM_TTY=y
687CONFIG_BT_BNEP=m
688# CONFIG_BT_BNEP_MC_FILTER is not set
689# CONFIG_BT_BNEP_PROTO_FILTER is not set
690# CONFIG_BT_HIDP is not set
691
692#
693# Bluetooth device drivers
694#
695CONFIG_BT_HCIUSB=m
696CONFIG_BT_HCIUSB_SCO=y
697CONFIG_BT_HCIBTSDIO=m
698CONFIG_BT_HCIUART=m
699CONFIG_BT_HCIUART_H4=y
700CONFIG_BT_HCIUART_BCSP=y
701CONFIG_BT_HCIUART_LL=y
702CONFIG_BT_HCIBCM203X=m
703CONFIG_BT_HCIBPA10X=m
704CONFIG_BT_HCIBFUSB=m
705CONFIG_BT_HCIVHCI=m
706# CONFIG_AF_RXRPC is not set
707CONFIG_FIB_RULES=y
708
709#
710# Wireless
711#
712CONFIG_CFG80211=m
713CONFIG_NL80211=y
714CONFIG_WIRELESS_EXT=y
715# CONFIG_WIRELESS_EXT_SYSFS is not set
716CONFIG_MAC80211=m
717
718#
719# Rate control algorithm selection
720#
721CONFIG_MAC80211_RC_PID=y
722CONFIG_MAC80211_RC_DEFAULT_PID=y
723CONFIG_MAC80211_RC_DEFAULT="pid"
724CONFIG_MAC80211_MESH=y
725CONFIG_MAC80211_LEDS=y
726CONFIG_MAC80211_DEBUGFS=y
727# CONFIG_MAC80211_DEBUG_MENU is not set
728CONFIG_IEEE80211=m
729# CONFIG_IEEE80211_DEBUG is not set
730CONFIG_IEEE80211_CRYPT_WEP=m
731CONFIG_IEEE80211_CRYPT_CCMP=m
732CONFIG_IEEE80211_CRYPT_TKIP=m
733CONFIG_RFKILL=m
734CONFIG_RFKILL_INPUT=m
735CONFIG_RFKILL_LEDS=y
736# CONFIG_NET_9P is not set
737
738#
739# Device Drivers
740#
741
742#
743# Generic Driver Options
744#
745CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
746CONFIG_STANDALONE=y
747CONFIG_PREVENT_FIRMWARE_BUILD=y
748CONFIG_FW_LOADER=y
749CONFIG_FIRMWARE_IN_KERNEL=y
750CONFIG_EXTRA_FIRMWARE=""
751# CONFIG_DEBUG_DRIVER is not set
752CONFIG_DEBUG_DEVRES=y
753# CONFIG_SYS_HYPERVISOR is not set
754CONFIG_CONNECTOR=y
755CONFIG_PROC_EVENTS=y
756# CONFIG_MTD is not set
757# CONFIG_PARPORT is not set
758CONFIG_PNP=y
759# CONFIG_PNP_DEBUG is not set
760
761#
762# Protocols
763#
764CONFIG_PNPACPI=y
765CONFIG_BLK_DEV=y
766# CONFIG_BLK_DEV_FD is not set
767# CONFIG_BLK_CPQ_DA is not set
768# CONFIG_BLK_CPQ_CISS_DA is not set
769# CONFIG_BLK_DEV_DAC960 is not set
770# CONFIG_BLK_DEV_UMEM is not set
771# CONFIG_BLK_DEV_COW_COMMON is not set
772CONFIG_BLK_DEV_LOOP=y
773CONFIG_BLK_DEV_CRYPTOLOOP=m
774# CONFIG_BLK_DEV_NBD is not set
775# CONFIG_BLK_DEV_SX8 is not set
776# CONFIG_BLK_DEV_UB is not set
777CONFIG_BLK_DEV_RAM=y
778CONFIG_BLK_DEV_RAM_COUNT=16
779CONFIG_BLK_DEV_RAM_SIZE=262144
780# CONFIG_BLK_DEV_XIP is not set
781CONFIG_CDROM_PKTCDVD=m
782CONFIG_CDROM_PKTCDVD_BUFFERS=8
783# CONFIG_CDROM_PKTCDVD_WCACHE is not set
784# CONFIG_ATA_OVER_ETH is not set
785# CONFIG_BLK_DEV_HD is not set
786CONFIG_MISC_DEVICES=y
787# CONFIG_IBM_ASM is not set
788# CONFIG_PHANTOM is not set
789CONFIG_EEPROM_93CX6=m
790# CONFIG_SGI_IOC4 is not set
791CONFIG_TIFM_CORE=m
792CONFIG_TIFM_7XX1=m
793# CONFIG_ACER_WMI is not set
794# CONFIG_FUJITSU_LAPTOP is not set
795# CONFIG_TC1100_WMI is not set
796# CONFIG_HP_WMI is not set
797# CONFIG_MSI_LAPTOP is not set
798# CONFIG_COMPAL_LAPTOP is not set
799# CONFIG_SONY_LAPTOP is not set
800# CONFIG_THINKPAD_ACPI is not set
801# CONFIG_INTEL_MENLOW is not set
802CONFIG_EEEPC_LAPTOP=y
803# CONFIG_ENCLOSURE_SERVICES is not set
804# CONFIG_HP_ILO is not set
805CONFIG_HAVE_IDE=y
806# CONFIG_IDE is not set
807
808#
809# SCSI device support
810#
811CONFIG_RAID_ATTRS=m
812CONFIG_SCSI=y
813CONFIG_SCSI_DMA=y
814# CONFIG_SCSI_TGT is not set
815# CONFIG_SCSI_NETLINK is not set
816CONFIG_SCSI_PROC_FS=y
817
818#
819# SCSI support type (disk, tape, CD-ROM)
820#
821CONFIG_BLK_DEV_SD=y
822CONFIG_CHR_DEV_ST=m
823# CONFIG_CHR_DEV_OSST is not set
824CONFIG_BLK_DEV_SR=y
825CONFIG_BLK_DEV_SR_VENDOR=y
826# CONFIG_CHR_DEV_SG is not set
827CONFIG_CHR_DEV_SCH=m
828
829#
830# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
831#
832CONFIG_SCSI_MULTI_LUN=y
833CONFIG_SCSI_CONSTANTS=y
834CONFIG_SCSI_LOGGING=y
835CONFIG_SCSI_SCAN_ASYNC=y
836CONFIG_SCSI_WAIT_SCAN=m
837
838#
839# SCSI Transports
840#
841# CONFIG_SCSI_SPI_ATTRS is not set
842# CONFIG_SCSI_FC_ATTRS is not set
843# CONFIG_SCSI_ISCSI_ATTRS is not set
844# CONFIG_SCSI_SAS_ATTRS is not set
845# CONFIG_SCSI_SAS_LIBSAS is not set
846# CONFIG_SCSI_SRP_ATTRS is not set
847CONFIG_SCSI_LOWLEVEL=y
848# CONFIG_ISCSI_TCP is not set
849# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
850# CONFIG_SCSI_3W_9XXX is not set
851# CONFIG_SCSI_ACARD is not set
852# CONFIG_SCSI_AACRAID is not set
853# CONFIG_SCSI_AIC7XXX is not set
854# CONFIG_SCSI_AIC7XXX_OLD is not set
855# CONFIG_SCSI_AIC79XX is not set
856# CONFIG_SCSI_AIC94XX is not set
857# CONFIG_SCSI_DPT_I2O is not set
858# CONFIG_SCSI_ADVANSYS is not set
859# CONFIG_SCSI_ARCMSR is not set
860# CONFIG_MEGARAID_NEWGEN is not set
861# CONFIG_MEGARAID_LEGACY is not set
862# CONFIG_MEGARAID_SAS is not set
863# CONFIG_SCSI_HPTIOP is not set
864# CONFIG_SCSI_BUSLOGIC is not set
865# CONFIG_SCSI_DMX3191D is not set
866# CONFIG_SCSI_EATA is not set
867# CONFIG_SCSI_FUTURE_DOMAIN is not set
868# CONFIG_SCSI_GDTH is not set
869# CONFIG_SCSI_IPS is not set
870# CONFIG_SCSI_INITIO is not set
871# CONFIG_SCSI_INIA100 is not set
872# CONFIG_SCSI_MVSAS is not set
873# CONFIG_SCSI_STEX is not set
874# CONFIG_SCSI_SYM53C8XX_2 is not set
875# CONFIG_SCSI_IPR is not set
876# CONFIG_SCSI_QLOGIC_1280 is not set
877# CONFIG_SCSI_QLA_FC is not set
878# CONFIG_SCSI_QLA_ISCSI is not set
879# CONFIG_SCSI_LPFC is not set
880# CONFIG_SCSI_DC395x is not set
881# CONFIG_SCSI_DC390T is not set
882# CONFIG_SCSI_NSP32 is not set
883# CONFIG_SCSI_DEBUG is not set
884# CONFIG_SCSI_SRP is not set
885# CONFIG_SCSI_DH is not set
886CONFIG_ATA=y
887# CONFIG_ATA_NONSTANDARD is not set
888CONFIG_ATA_ACPI=y
889# CONFIG_SATA_PMP is not set
890CONFIG_SATA_AHCI=y
891# CONFIG_SATA_SIL24 is not set
892CONFIG_ATA_SFF=y
893# CONFIG_SATA_SVW is not set
894CONFIG_ATA_PIIX=y
895# CONFIG_SATA_MV is not set
896# CONFIG_SATA_NV is not set
897# CONFIG_PDC_ADMA is not set
898# CONFIG_SATA_QSTOR is not set
899# CONFIG_SATA_PROMISE is not set
900# CONFIG_SATA_SX4 is not set
901# CONFIG_SATA_SIL is not set
902# CONFIG_SATA_SIS is not set
903# CONFIG_SATA_ULI is not set
904# CONFIG_SATA_VIA is not set
905# CONFIG_SATA_VITESSE is not set
906# CONFIG_SATA_INIC162X is not set
907# CONFIG_PATA_ACPI is not set
908# CONFIG_PATA_ALI is not set
909# CONFIG_PATA_AMD is not set
910# CONFIG_PATA_ARTOP is not set
911# CONFIG_PATA_ATIIXP is not set
912# CONFIG_PATA_CMD640_PCI is not set
913# CONFIG_PATA_CMD64X is not set
914# CONFIG_PATA_CS5520 is not set
915# CONFIG_PATA_CS5530 is not set
916# CONFIG_PATA_CS5535 is not set
917# CONFIG_PATA_CS5536 is not set
918# CONFIG_PATA_CYPRESS is not set
919# CONFIG_PATA_EFAR is not set
920# CONFIG_ATA_GENERIC is not set
921# CONFIG_PATA_HPT366 is not set
922# CONFIG_PATA_HPT37X is not set
923# CONFIG_PATA_HPT3X2N is not set
924# CONFIG_PATA_HPT3X3 is not set
925# CONFIG_PATA_IT821X is not set
926# CONFIG_PATA_IT8213 is not set
927# CONFIG_PATA_JMICRON is not set
928# CONFIG_PATA_TRIFLEX is not set
929# CONFIG_PATA_MARVELL is not set
930# CONFIG_PATA_MPIIX is not set
931# CONFIG_PATA_OLDPIIX is not set
932# CONFIG_PATA_NETCELL is not set
933# CONFIG_PATA_NINJA32 is not set
934# CONFIG_PATA_NS87410 is not set
935# CONFIG_PATA_NS87415 is not set
936# CONFIG_PATA_OPTI is not set
937# CONFIG_PATA_OPTIDMA is not set
938# CONFIG_PATA_PDC_OLD is not set
939# CONFIG_PATA_RADISYS is not set
940# CONFIG_PATA_RZ1000 is not set
941# CONFIG_PATA_SC1200 is not set
942# CONFIG_PATA_SERVERWORKS is not set
943# CONFIG_PATA_PDC2027X is not set
944# CONFIG_PATA_SIL680 is not set
945# CONFIG_PATA_SIS is not set
946# CONFIG_PATA_VIA is not set
947# CONFIG_PATA_WINBOND is not set
948CONFIG_PATA_SCH=y
949# CONFIG_MD is not set
950# CONFIG_FUSION is not set
951
952#
953# IEEE 1394 (FireWire) support
954#
955
956#
957# Enable only one of the two stacks, unless you know what you are doing
958#
959# CONFIG_FIREWIRE is not set
960# CONFIG_IEEE1394 is not set
961# CONFIG_I2O is not set
962# CONFIG_MACINTOSH_DRIVERS is not set
963CONFIG_NETDEVICES=y
964# CONFIG_DUMMY is not set
965# CONFIG_BONDING is not set
966CONFIG_MACVLAN=m
967# CONFIG_EQUALIZER is not set
968# CONFIG_TUN is not set
969# CONFIG_VETH is not set
970# CONFIG_NET_SB1000 is not set
971# CONFIG_ARCNET is not set
972CONFIG_PHYLIB=m
973
974#
975# MII PHY device drivers
976#
977CONFIG_MARVELL_PHY=m
978CONFIG_DAVICOM_PHY=m
979CONFIG_QSEMI_PHY=m
980CONFIG_LXT_PHY=m
981CONFIG_CICADA_PHY=m
982CONFIG_VITESSE_PHY=m
983CONFIG_SMSC_PHY=m
984CONFIG_BROADCOM_PHY=m
985CONFIG_ICPLUS_PHY=m
986CONFIG_REALTEK_PHY=m
987CONFIG_MDIO_BITBANG=m
988CONFIG_NET_ETHERNET=y
989CONFIG_MII=m
990CONFIG_HAPPYMEAL=m
991CONFIG_SUNGEM=m
992CONFIG_CASSINI=m
993CONFIG_NET_VENDOR_3COM=y
994# CONFIG_VORTEX is not set
995# CONFIG_TYPHOON is not set
996# CONFIG_NET_TULIP is not set
997# CONFIG_HP100 is not set
998# CONFIG_IBM_NEW_EMAC_ZMII is not set
999# CONFIG_IBM_NEW_EMAC_RGMII is not set
1000# CONFIG_IBM_NEW_EMAC_TAH is not set
1001# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
1002# CONFIG_NET_PCI is not set
1003# CONFIG_B44 is not set
1004CONFIG_NETDEV_1000=y
1005# CONFIG_ACENIC is not set
1006# CONFIG_DL2K is not set
1007# CONFIG_E1000 is not set
1008# CONFIG_E1000E is not set
1009# CONFIG_IP1000 is not set
1010# CONFIG_IGB is not set
1011# CONFIG_NS83820 is not set
1012# CONFIG_HAMACHI is not set
1013# CONFIG_YELLOWFIN is not set
1014# CONFIG_R8169 is not set
1015# CONFIG_SIS190 is not set
1016# CONFIG_SKGE is not set
1017# CONFIG_SKY2 is not set
1018# CONFIG_VIA_VELOCITY is not set
1019# CONFIG_TIGON3 is not set
1020# CONFIG_BNX2 is not set
1021# CONFIG_QLA3XXX is not set
1022CONFIG_ATL1=m
1023CONFIG_ATL1E=m
1024# CONFIG_NETDEV_10000 is not set
1025# CONFIG_TR is not set
1026
1027#
1028# Wireless LAN
1029#
1030CONFIG_WLAN_PRE80211=y
1031# CONFIG_STRIP is not set
1032CONFIG_WLAN_80211=y
1033# CONFIG_IPW2100 is not set
1034# CONFIG_IPW2200 is not set
1035# CONFIG_LIBERTAS is not set
1036# CONFIG_AIRO is not set
1037# CONFIG_HERMES is not set
1038# CONFIG_ATMEL is not set
1039# CONFIG_PRISM54 is not set
1040CONFIG_USB_ZD1201=m
1041CONFIG_USB_NET_RNDIS_WLAN=m
1042CONFIG_RTL8180=m
1043CONFIG_RTL8187=m
1044# CONFIG_ADM8211 is not set
1045# CONFIG_MAC80211_HWSIM is not set
1046# CONFIG_P54_COMMON is not set
1047CONFIG_ATH5K=m
1048# CONFIG_ATH5K_DEBUG is not set
1049CONFIG_IWLWIFI=m
1050CONFIG_IWLCORE=m
1051# CONFIG_IWLWIFI_LEDS is not set
1052CONFIG_IWLWIFI_RFKILL=y
1053CONFIG_IWL4965=m
1054# CONFIG_IWL4965_LEDS is not set
1055# CONFIG_IWL4965_SPECTRUM_MEASUREMENT is not set
1056# CONFIG_IWLWIFI_DEBUG is not set
1057CONFIG_IWL5000=y
1058CONFIG_IWL3945=m
1059CONFIG_IWL3945_RFKILL=y
1060# CONFIG_IWL3945_SPECTRUM_MEASUREMENT is not set
1061# CONFIG_IWL3945_LEDS is not set
1062# CONFIG_IWL3945_DEBUG is not set
1063# CONFIG_HOSTAP is not set
1064# CONFIG_B43 is not set
1065# CONFIG_B43LEGACY is not set
1066# CONFIG_ZD1211RW is not set
1067CONFIG_RT2X00=m
1068CONFIG_RT2X00_LIB=m
1069CONFIG_RT2X00_LIB_PCI=m
1070CONFIG_RT2X00_LIB_USB=m
1071CONFIG_RT2X00_LIB_FIRMWARE=y
1072CONFIG_RT2X00_LIB_RFKILL=y
1073CONFIG_RT2X00_LIB_LEDS=y
1074CONFIG_RT2400PCI=m
1075CONFIG_RT2400PCI_RFKILL=y
1076CONFIG_RT2400PCI_LEDS=y
1077CONFIG_RT2500PCI=m
1078CONFIG_RT2500PCI_RFKILL=y
1079CONFIG_RT2500PCI_LEDS=y
1080CONFIG_RT61PCI=m
1081CONFIG_RT61PCI_RFKILL=y
1082CONFIG_RT61PCI_LEDS=y
1083CONFIG_RT2500USB=m
1084CONFIG_RT2500USB_LEDS=y
1085CONFIG_RT73USB=m
1086CONFIG_RT73USB_LEDS=y
1087CONFIG_RT2X00_LIB_DEBUGFS=y
1088# CONFIG_RT2X00_DEBUG is not set
1089
1090#
1091# USB Network Adapters
1092#
1093CONFIG_USB_CATC=m
1094CONFIG_USB_KAWETH=m
1095CONFIG_USB_PEGASUS=m
1096CONFIG_USB_RTL8150=m
1097CONFIG_USB_USBNET=m
1098CONFIG_USB_NET_AX8817X=m
1099# CONFIG_USB_HSO is not set
1100CONFIG_USB_NET_CDCETHER=m
1101CONFIG_USB_NET_DM9601=m
1102CONFIG_USB_NET_GL620A=m
1103CONFIG_USB_NET_NET1080=m
1104CONFIG_USB_NET_PLUSB=m
1105CONFIG_USB_NET_MCS7830=m
1106CONFIG_USB_NET_RNDIS_HOST=m
1107CONFIG_USB_NET_CDC_SUBSET=m
1108CONFIG_USB_ALI_M5632=y
1109CONFIG_USB_AN2720=y
1110CONFIG_USB_BELKIN=y
1111CONFIG_USB_ARMLINUX=y
1112CONFIG_USB_EPSON2888=y
1113CONFIG_USB_KC2190=y
1114CONFIG_USB_NET_ZAURUS=m
1115# CONFIG_WAN is not set
1116# CONFIG_FDDI is not set
1117# CONFIG_HIPPI is not set
1118CONFIG_PPP=m
1119CONFIG_PPP_MULTILINK=y
1120CONFIG_PPP_FILTER=y
1121CONFIG_PPP_ASYNC=m
1122CONFIG_PPP_SYNC_TTY=m
1123CONFIG_PPP_DEFLATE=m
1124# CONFIG_PPP_BSDCOMP is not set
1125CONFIG_PPP_MPPE=m
1126CONFIG_PPPOE=m
1127CONFIG_PPPOL2TP=m
1128# CONFIG_SLIP is not set
1129CONFIG_SLHC=m
1130CONFIG_NET_FC=y
1131CONFIG_NETCONSOLE=m
1132CONFIG_NETCONSOLE_DYNAMIC=y
1133CONFIG_NETPOLL=y
1134CONFIG_NETPOLL_TRAP=y
1135CONFIG_NET_POLL_CONTROLLER=y
1136# CONFIG_ISDN is not set
1137# CONFIG_PHONE is not set
1138
1139#
1140# Input device support
1141#
1142CONFIG_INPUT=y
1143CONFIG_INPUT_FF_MEMLESS=y
1144CONFIG_INPUT_POLLDEV=m
1145
1146#
1147# Userland interfaces
1148#
1149CONFIG_INPUT_MOUSEDEV=y
1150# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
1151CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
1152CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
1153CONFIG_INPUT_JOYDEV=m
1154CONFIG_INPUT_EVDEV=y
1155# CONFIG_INPUT_EVBUG is not set
1156
1157#
1158# Input Device Drivers
1159#
1160CONFIG_INPUT_KEYBOARD=y
1161CONFIG_KEYBOARD_ATKBD=y
1162# CONFIG_KEYBOARD_SUNKBD is not set
1163# CONFIG_KEYBOARD_LKKBD is not set
1164# CONFIG_KEYBOARD_XTKBD is not set
1165# CONFIG_KEYBOARD_NEWTON is not set
1166# CONFIG_KEYBOARD_STOWAWAY is not set
1167CONFIG_INPUT_MOUSE=y
1168CONFIG_MOUSE_PS2=y
1169CONFIG_MOUSE_PS2_ALPS=y
1170CONFIG_MOUSE_PS2_LOGIPS2PP=y
1171CONFIG_MOUSE_PS2_SYNAPTICS=y
1172CONFIG_MOUSE_PS2_LIFEBOOK=y
1173CONFIG_MOUSE_PS2_TRACKPOINT=y
1174# CONFIG_MOUSE_PS2_TOUCHKIT is not set
1175CONFIG_MOUSE_SERIAL=m
1176# CONFIG_MOUSE_APPLETOUCH is not set
1177CONFIG_MOUSE_VSXXXAA=m
1178CONFIG_INPUT_JOYSTICK=y
1179# CONFIG_JOYSTICK_ANALOG is not set
1180# CONFIG_JOYSTICK_A3D is not set
1181# CONFIG_JOYSTICK_ADI is not set
1182# CONFIG_JOYSTICK_COBRA is not set
1183# CONFIG_JOYSTICK_GF2K is not set
1184# CONFIG_JOYSTICK_GRIP is not set
1185# CONFIG_JOYSTICK_GRIP_MP is not set
1186# CONFIG_JOYSTICK_GUILLEMOT is not set
1187# CONFIG_JOYSTICK_INTERACT is not set
1188# CONFIG_JOYSTICK_SIDEWINDER is not set
1189# CONFIG_JOYSTICK_TMDC is not set
1190# CONFIG_JOYSTICK_IFORCE is not set
1191# CONFIG_JOYSTICK_WARRIOR is not set
1192# CONFIG_JOYSTICK_MAGELLAN is not set
1193# CONFIG_JOYSTICK_SPACEORB is not set
1194# CONFIG_JOYSTICK_SPACEBALL is not set
1195# CONFIG_JOYSTICK_STINGER is not set
1196# CONFIG_JOYSTICK_TWIDJOY is not set
1197# CONFIG_JOYSTICK_ZHENHUA is not set
1198# CONFIG_JOYSTICK_JOYDUMP is not set
1199# CONFIG_JOYSTICK_XPAD is not set
1200# CONFIG_INPUT_TABLET is not set
1201CONFIG_INPUT_TOUCHSCREEN=y
1202CONFIG_TOUCHSCREEN_FUJITSU=m
1203CONFIG_TOUCHSCREEN_GUNZE=m
1204CONFIG_TOUCHSCREEN_ELO=m
1205CONFIG_TOUCHSCREEN_MTOUCH=m
1206CONFIG_TOUCHSCREEN_INEXIO=m
1207CONFIG_TOUCHSCREEN_MK712=m
1208CONFIG_TOUCHSCREEN_PENMOUNT=m
1209CONFIG_TOUCHSCREEN_TOUCHRIGHT=m
1210CONFIG_TOUCHSCREEN_TOUCHWIN=m
1211CONFIG_TOUCHSCREEN_UCB1400=m
1212# CONFIG_TOUCHSCREEN_WM97XX is not set
1213CONFIG_TOUCHSCREEN_USB_COMPOSITE=m
1214CONFIG_TOUCHSCREEN_USB_EGALAX=y
1215CONFIG_TOUCHSCREEN_USB_PANJIT=y
1216CONFIG_TOUCHSCREEN_USB_3M=y
1217CONFIG_TOUCHSCREEN_USB_ITM=y
1218CONFIG_TOUCHSCREEN_USB_ETURBO=y
1219CONFIG_TOUCHSCREEN_USB_GUNZE=y
1220CONFIG_TOUCHSCREEN_USB_DMC_TSC10=y
1221CONFIG_TOUCHSCREEN_USB_IRTOUCH=y
1222CONFIG_TOUCHSCREEN_USB_IDEALTEK=y
1223CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH=y
1224CONFIG_TOUCHSCREEN_USB_GOTOP=y
1225CONFIG_TOUCHSCREEN_TOUCHIT213=m
1226CONFIG_INPUT_MISC=y
1227# CONFIG_INPUT_PCSPKR is not set
1228# CONFIG_INPUT_APANEL is not set
1229# CONFIG_INPUT_WISTRON_BTNS is not set
1230CONFIG_INPUT_ATLAS_BTNS=m
1231CONFIG_INPUT_ATI_REMOTE=m
1232CONFIG_INPUT_ATI_REMOTE2=m
1233CONFIG_INPUT_KEYSPAN_REMOTE=m
1234CONFIG_INPUT_POWERMATE=m
1235CONFIG_INPUT_YEALINK=m
1236CONFIG_INPUT_UINPUT=m
1237
1238#
1239# Hardware I/O ports
1240#
1241CONFIG_SERIO=y
1242CONFIG_SERIO_I8042=y
1243CONFIG_SERIO_SERPORT=y
1244# CONFIG_SERIO_CT82C710 is not set
1245# CONFIG_SERIO_PCIPS2 is not set
1246CONFIG_SERIO_LIBPS2=y
1247CONFIG_SERIO_RAW=m
1248# CONFIG_GAMEPORT is not set
1249
1250#
1251# Character devices
1252#
1253CONFIG_VT=y
1254CONFIG_CONSOLE_TRANSLATIONS=y
1255CONFIG_VT_CONSOLE=y
1256CONFIG_HW_CONSOLE=y
1257CONFIG_VT_HW_CONSOLE_BINDING=y
1258# CONFIG_DEVKMEM is not set
1259# CONFIG_SERIAL_NONSTANDARD is not set
1260# CONFIG_NOZOMI is not set
1261
1262#
1263# Serial drivers
1264#
1265# CONFIG_SERIAL_8250 is not set
1266CONFIG_FIX_EARLYCON_MEM=y
1267
1268#
1269# Non-8250 serial port support
1270#
1271# CONFIG_SERIAL_JSM is not set
1272CONFIG_UNIX98_PTYS=y
1273# CONFIG_LEGACY_PTYS is not set
1274# CONFIG_IPMI_HANDLER is not set
1275# CONFIG_HW_RANDOM is not set
1276# CONFIG_NVRAM is not set
1277# CONFIG_R3964 is not set
1278# CONFIG_APPLICOM is not set
1279# CONFIG_SONYPI is not set
1280# CONFIG_MWAVE is not set
1281# CONFIG_PC8736x_GPIO is not set
1282# CONFIG_NSC_GPIO is not set
1283# CONFIG_CS5535_GPIO is not set
1284# CONFIG_RAW_DRIVER is not set
1285CONFIG_HPET=y
1286# CONFIG_HPET_MMAP is not set
1287# CONFIG_HANGCHECK_TIMER is not set
1288# CONFIG_TCG_TPM is not set
1289# CONFIG_TELCLOCK is not set
1290CONFIG_DEVPORT=y
1291CONFIG_I2C=y
1292CONFIG_I2C_BOARDINFO=y
1293# CONFIG_I2C_CHARDEV is not set
1294CONFIG_I2C_ALGOBIT=y
1295
1296#
1297# I2C Hardware Bus support
1298#
1299
1300#
1301# PC SMBus host controller drivers
1302#
1303# CONFIG_I2C_ALI1535 is not set
1304# CONFIG_I2C_ALI1563 is not set
1305# CONFIG_I2C_ALI15X3 is not set
1306# CONFIG_I2C_AMD756 is not set
1307# CONFIG_I2C_AMD8111 is not set
1308# CONFIG_I2C_I801 is not set
1309# CONFIG_I2C_ISCH is not set
1310# CONFIG_I2C_PIIX4 is not set
1311# CONFIG_I2C_NFORCE2 is not set
1312# CONFIG_I2C_SIS5595 is not set
1313# CONFIG_I2C_SIS630 is not set
1314# CONFIG_I2C_SIS96X is not set
1315# CONFIG_I2C_VIA is not set
1316# CONFIG_I2C_VIAPRO is not set
1317
1318#
1319# I2C system bus drivers (mostly embedded / system-on-chip)
1320#
1321# CONFIG_I2C_OCORES is not set
1322# CONFIG_I2C_SIMTEC is not set
1323
1324#
1325# External I2C/SMBus adapter drivers
1326#
1327# CONFIG_I2C_PARPORT_LIGHT is not set
1328# CONFIG_I2C_TAOS_EVM is not set
1329# CONFIG_I2C_TINY_USB is not set
1330
1331#
1332# Graphics adapter I2C/DDC channel drivers
1333#
1334# CONFIG_I2C_VOODOO3 is not set
1335
1336#
1337# Other I2C/SMBus bus drivers
1338#
1339# CONFIG_I2C_PCA_PLATFORM is not set
1340# CONFIG_I2C_STUB is not set
1341# CONFIG_SCx200_ACB is not set
1342
1343#
1344# Miscellaneous I2C Chip support
1345#
1346# CONFIG_DS1682 is not set
1347# CONFIG_AT24 is not set
1348# CONFIG_SENSORS_EEPROM is not set
1349# CONFIG_SENSORS_PCF8574 is not set
1350# CONFIG_PCF8575 is not set
1351# CONFIG_SENSORS_PCA9539 is not set
1352# CONFIG_SENSORS_PCF8591 is not set
1353# CONFIG_SENSORS_MAX6875 is not set
1354# CONFIG_SENSORS_TSL2550 is not set
1355# CONFIG_I2C_DEBUG_CORE is not set
1356# CONFIG_I2C_DEBUG_ALGO is not set
1357# CONFIG_I2C_DEBUG_BUS is not set
1358# CONFIG_I2C_DEBUG_CHIP is not set
1359# CONFIG_SPI is not set
1360CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
1361# CONFIG_GPIOLIB is not set
1362# CONFIG_W1 is not set
1363CONFIG_POWER_SUPPLY=y
1364# CONFIG_POWER_SUPPLY_DEBUG is not set
1365# CONFIG_PDA_POWER is not set
1366# CONFIG_BATTERY_DS2760 is not set
1367CONFIG_HWMON=y
1368# CONFIG_HWMON_VID is not set
1369# CONFIG_SENSORS_ABITUGURU is not set
1370# CONFIG_SENSORS_ABITUGURU3 is not set
1371# CONFIG_SENSORS_AD7418 is not set
1372# CONFIG_SENSORS_ADM1021 is not set
1373# CONFIG_SENSORS_ADM1025 is not set
1374# CONFIG_SENSORS_ADM1026 is not set
1375# CONFIG_SENSORS_ADM1029 is not set
1376# CONFIG_SENSORS_ADM1031 is not set
1377# CONFIG_SENSORS_ADM9240 is not set
1378# CONFIG_SENSORS_ADT7470 is not set
1379# CONFIG_SENSORS_ADT7473 is not set
1380# CONFIG_SENSORS_K8TEMP is not set
1381# CONFIG_SENSORS_ASB100 is not set
1382# CONFIG_SENSORS_ATXP1 is not set
1383# CONFIG_SENSORS_DS1621 is not set
1384# CONFIG_SENSORS_I5K_AMB is not set
1385# CONFIG_SENSORS_F71805F is not set
1386# CONFIG_SENSORS_F71882FG is not set
1387# CONFIG_SENSORS_F75375S is not set
1388# CONFIG_SENSORS_FSCHER is not set
1389# CONFIG_SENSORS_FSCPOS is not set
1390# CONFIG_SENSORS_FSCHMD is not set
1391# CONFIG_SENSORS_GL518SM is not set
1392# CONFIG_SENSORS_GL520SM is not set
1393CONFIG_SENSORS_CORETEMP=y
1394# CONFIG_SENSORS_IT87 is not set
1395# CONFIG_SENSORS_LM63 is not set
1396# CONFIG_SENSORS_LM75 is not set
1397# CONFIG_SENSORS_LM77 is not set
1398# CONFIG_SENSORS_LM78 is not set
1399# CONFIG_SENSORS_LM80 is not set
1400# CONFIG_SENSORS_LM83 is not set
1401# CONFIG_SENSORS_LM85 is not set
1402# CONFIG_SENSORS_LM87 is not set
1403# CONFIG_SENSORS_LM90 is not set
1404# CONFIG_SENSORS_LM92 is not set
1405# CONFIG_SENSORS_LM93 is not set
1406# CONFIG_SENSORS_MAX1619 is not set
1407# CONFIG_SENSORS_MAX6650 is not set
1408# CONFIG_SENSORS_PC87360 is not set
1409# CONFIG_SENSORS_PC87427 is not set
1410# CONFIG_SENSORS_SIS5595 is not set
1411# CONFIG_SENSORS_DME1737 is not set
1412# CONFIG_SENSORS_SMSC47M1 is not set
1413# CONFIG_SENSORS_SMSC47M192 is not set
1414# CONFIG_SENSORS_SMSC47B397 is not set
1415# CONFIG_SENSORS_ADS7828 is not set
1416# CONFIG_SENSORS_THMC50 is not set
1417# CONFIG_SENSORS_VIA686A is not set
1418# CONFIG_SENSORS_VT1211 is not set
1419# CONFIG_SENSORS_VT8231 is not set
1420# CONFIG_SENSORS_W83781D is not set
1421# CONFIG_SENSORS_W83791D is not set
1422# CONFIG_SENSORS_W83792D is not set
1423# CONFIG_SENSORS_W83793 is not set
1424# CONFIG_SENSORS_W83L785TS is not set
1425# CONFIG_SENSORS_W83L786NG is not set
1426# CONFIG_SENSORS_W83627HF is not set
1427# CONFIG_SENSORS_W83627EHF is not set
1428# CONFIG_SENSORS_HDAPS is not set
1429# CONFIG_SENSORS_APPLESMC is not set
1430# CONFIG_HWMON_DEBUG_CHIP is not set
1431CONFIG_THERMAL=y
1432# CONFIG_THERMAL_HWMON is not set
1433# CONFIG_WATCHDOG is not set
1434
1435#
1436# Sonics Silicon Backplane
1437#
1438CONFIG_SSB_POSSIBLE=y
1439# CONFIG_SSB is not set
1440
1441#
1442# Multifunction device drivers
1443#
1444# CONFIG_MFD_CORE is not set
1445# CONFIG_MFD_SM501 is not set
1446# CONFIG_HTC_PASIC3 is not set
1447
1448#
1449# Multimedia devices
1450#
1451
1452#
1453# Multimedia core support
1454#
1455CONFIG_VIDEO_DEV=y
1456CONFIG_VIDEO_V4L2_COMMON=y
1457# CONFIG_VIDEO_ALLOW_V4L1 is not set
1458CONFIG_VIDEO_V4L1_COMPAT=y
1459CONFIG_DVB_CORE=y
1460CONFIG_VIDEO_MEDIA=y
1461
1462#
1463# Multimedia drivers
1464#
1465# CONFIG_MEDIA_ATTACH is not set
1466CONFIG_MEDIA_TUNER=y
1467# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set
1468CONFIG_MEDIA_TUNER_SIMPLE=y
1469CONFIG_MEDIA_TUNER_TDA8290=y
1470CONFIG_MEDIA_TUNER_TDA9887=y
1471CONFIG_MEDIA_TUNER_TEA5761=y
1472CONFIG_MEDIA_TUNER_TEA5767=y
1473CONFIG_MEDIA_TUNER_MT20XX=y
1474CONFIG_MEDIA_TUNER_XC2028=y
1475CONFIG_MEDIA_TUNER_XC5000=y
1476CONFIG_VIDEO_V4L2=y
1477CONFIG_VIDEO_CAPTURE_DRIVERS=y
1478# CONFIG_VIDEO_ADV_DEBUG is not set
1479CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
1480# CONFIG_VIDEO_VIVI is not set
1481# CONFIG_VIDEO_BT848 is not set
1482# CONFIG_VIDEO_SAA5246A is not set
1483# CONFIG_VIDEO_SAA5249 is not set
1484# CONFIG_VIDEO_SAA7134 is not set
1485# CONFIG_VIDEO_HEXIUM_ORION is not set
1486# CONFIG_VIDEO_HEXIUM_GEMINI is not set
1487# CONFIG_VIDEO_CX88 is not set
1488# CONFIG_VIDEO_CX23885 is not set
1489# CONFIG_VIDEO_AU0828 is not set
1490# CONFIG_VIDEO_CX18 is not set
1491# CONFIG_VIDEO_CAFE_CCIC is not set
1492CONFIG_V4L_USB_DRIVERS=y
1493CONFIG_USB_VIDEO_CLASS=y
1494CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y
1495# CONFIG_USB_GSPCA is not set
1496# CONFIG_VIDEO_PVRUSB2 is not set
1497# CONFIG_VIDEO_EM28XX is not set
1498# CONFIG_VIDEO_USBVISION is not set
1499# CONFIG_USB_ET61X251 is not set
1500# CONFIG_USB_SN9C102 is not set
1501# CONFIG_USB_ZC0301 is not set
1502# CONFIG_USB_ZR364XX is not set
1503# CONFIG_USB_STKWEBCAM is not set
1504# CONFIG_USB_S2255 is not set
1505# CONFIG_SOC_CAMERA is not set
1506# CONFIG_VIDEO_SH_MOBILE_CEU is not set
1507# CONFIG_RADIO_ADAPTERS is not set
1508# CONFIG_DVB_CAPTURE_DRIVERS is not set
1509# CONFIG_DAB is not set
1510
1511#
1512# Graphics support
1513#
1514CONFIG_AGP=y
1515# CONFIG_AGP_ALI is not set
1516# CONFIG_AGP_ATI is not set
1517# CONFIG_AGP_AMD is not set
1518CONFIG_AGP_AMD64=y
1519CONFIG_AGP_INTEL=y
1520# CONFIG_AGP_NVIDIA is not set
1521# CONFIG_AGP_SIS is not set
1522# CONFIG_AGP_SWORKS is not set
1523# CONFIG_AGP_VIA is not set
1524# CONFIG_AGP_EFFICEON is not set
1525CONFIG_DRM=y
1526# CONFIG_DRM_TDFX is not set
1527# CONFIG_DRM_R128 is not set
1528# CONFIG_DRM_RADEON is not set
1529CONFIG_DRM_I810=y
1530# CONFIG_DRM_I830 is not set
1531CONFIG_DRM_I915=y
1532# CONFIG_DRM_MGA is not set
1533# CONFIG_DRM_SIS is not set
1534# CONFIG_DRM_VIA is not set
1535# CONFIG_DRM_SAVAGE is not set
1536# CONFIG_VGASTATE is not set
1537CONFIG_VIDEO_OUTPUT_CONTROL=y
1538CONFIG_FB=y
1539CONFIG_FIRMWARE_EDID=y
1540CONFIG_FB_DDC=y
1541CONFIG_FB_CFB_FILLRECT=y
1542CONFIG_FB_CFB_COPYAREA=y
1543CONFIG_FB_CFB_IMAGEBLIT=y
1544# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
1545# CONFIG_FB_SYS_FILLRECT is not set
1546# CONFIG_FB_SYS_COPYAREA is not set
1547# CONFIG_FB_SYS_IMAGEBLIT is not set
1548# CONFIG_FB_FOREIGN_ENDIAN is not set
1549# CONFIG_FB_SYS_FOPS is not set
1550# CONFIG_FB_SVGALIB is not set
1551# CONFIG_FB_MACMODES is not set
1552# CONFIG_FB_BACKLIGHT is not set
1553CONFIG_FB_MODE_HELPERS=y
1554# CONFIG_FB_TILEBLITTING is not set
1555
1556#
1557# Frame buffer hardware drivers
1558#
1559# CONFIG_FB_CIRRUS is not set
1560# CONFIG_FB_PM2 is not set
1561# CONFIG_FB_CYBER2000 is not set
1562# CONFIG_FB_ARC is not set
1563# CONFIG_FB_ASILIANT is not set
1564# CONFIG_FB_IMSTT is not set
1565# CONFIG_FB_VGA16 is not set
1566# CONFIG_FB_UVESA is not set
1567# CONFIG_FB_VESA is not set
1568# CONFIG_FB_EFI is not set
1569# CONFIG_FB_N411 is not set
1570# CONFIG_FB_HGA is not set
1571# CONFIG_FB_S1D13XXX is not set
1572# CONFIG_FB_NVIDIA is not set
1573# CONFIG_FB_RIVA is not set
1574# CONFIG_FB_I810 is not set
1575# CONFIG_FB_LE80578 is not set
1576CONFIG_FB_INTEL=y
1577CONFIG_FB_INTEL_DEBUG=y
1578CONFIG_FB_INTEL_I2C=y
1579# CONFIG_FB_MATROX is not set
1580# CONFIG_FB_RADEON is not set
1581# CONFIG_FB_ATY128 is not set
1582# CONFIG_FB_ATY is not set
1583# CONFIG_FB_S3 is not set
1584# CONFIG_FB_SAVAGE is not set
1585# CONFIG_FB_SIS is not set
1586# CONFIG_FB_NEOMAGIC is not set
1587# CONFIG_FB_KYRO is not set
1588# CONFIG_FB_3DFX is not set
1589# CONFIG_FB_VOODOO1 is not set
1590# CONFIG_FB_VT8623 is not set
1591# CONFIG_FB_CYBLA is not set
1592# CONFIG_FB_TRIDENT is not set
1593# CONFIG_FB_ARK is not set
1594# CONFIG_FB_PM3 is not set
1595# CONFIG_FB_CARMINE is not set
1596# CONFIG_FB_GEODE is not set
1597# CONFIG_FB_VIRTUAL is not set
1598CONFIG_BACKLIGHT_LCD_SUPPORT=y
1599CONFIG_LCD_CLASS_DEVICE=y
1600# CONFIG_LCD_ILI9320 is not set
1601CONFIG_LCD_PLATFORM=y
1602CONFIG_BACKLIGHT_CLASS_DEVICE=y
1603# CONFIG_BACKLIGHT_CORGI is not set
1604# CONFIG_BACKLIGHT_PROGEAR is not set
1605CONFIG_BACKLIGHT_MBP_NVIDIA=y
1606
1607#
1608# Display device support
1609#
1610CONFIG_DISPLAY_SUPPORT=y
1611
1612#
1613# Display hardware drivers
1614#
1615
1616#
1617# Console display driver support
1618#
1619CONFIG_VGA_CONSOLE=y
1620CONFIG_VGACON_SOFT_SCROLLBACK=y
1621CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=64
1622CONFIG_VIDEO_SELECT=y
1623CONFIG_DUMMY_CONSOLE=y
1624CONFIG_FRAMEBUFFER_CONSOLE=y
1625# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
1626# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
1627# CONFIG_FONTS is not set
1628CONFIG_FONT_8x8=y
1629CONFIG_FONT_8x16=y
1630# CONFIG_LOGO is not set
1631CONFIG_SOUND=y
1632CONFIG_SND=y
1633CONFIG_SND_TIMER=y
1634CONFIG_SND_PCM=y
1635CONFIG_SND_HWDEP=y
1636CONFIG_SND_RAWMIDI=m
1637CONFIG_SND_SEQUENCER=y
1638CONFIG_SND_SEQ_DUMMY=y
1639# CONFIG_SND_MIXER_OSS is not set
1640# CONFIG_SND_PCM_OSS is not set
1641# CONFIG_SND_SEQUENCER_OSS is not set
1642CONFIG_SND_DYNAMIC_MINORS=y
1643# CONFIG_SND_SUPPORT_OLD_API is not set
1644CONFIG_SND_VERBOSE_PROCFS=y
1645CONFIG_SND_VERBOSE_PRINTK=y
1646CONFIG_SND_DEBUG=y
1647# CONFIG_SND_DEBUG_VERBOSE is not set
1648CONFIG_SND_PCM_XRUN_DEBUG=y
1649CONFIG_SND_VMASTER=y
1650CONFIG_SND_AC97_CODEC=y
1651CONFIG_SND_DRIVERS=y
1652# CONFIG_SND_PCSP is not set
1653# CONFIG_SND_DUMMY is not set
1654# CONFIG_SND_VIRMIDI is not set
1655# CONFIG_SND_MTPAV is not set
1656# CONFIG_SND_SERIAL_U16550 is not set
1657# CONFIG_SND_MPU401 is not set
1658CONFIG_SND_AC97_POWER_SAVE=y
1659CONFIG_SND_AC97_POWER_SAVE_DEFAULT=5
1660CONFIG_SND_PCI=y
1661# CONFIG_SND_AD1889 is not set
1662# CONFIG_SND_ALS300 is not set
1663# CONFIG_SND_ALS4000 is not set
1664# CONFIG_SND_ALI5451 is not set
1665# CONFIG_SND_ATIIXP is not set
1666# CONFIG_SND_ATIIXP_MODEM is not set
1667# CONFIG_SND_AU8810 is not set
1668# CONFIG_SND_AU8820 is not set
1669# CONFIG_SND_AU8830 is not set
1670# CONFIG_SND_AW2 is not set
1671# CONFIG_SND_AZT3328 is not set
1672# CONFIG_SND_BT87X is not set
1673# CONFIG_SND_CA0106 is not set
1674# CONFIG_SND_CMIPCI is not set
1675# CONFIG_SND_OXYGEN is not set
1676# CONFIG_SND_CS4281 is not set
1677# CONFIG_SND_CS46XX is not set
1678# CONFIG_SND_CS5530 is not set
1679# CONFIG_SND_CS5535AUDIO is not set
1680# CONFIG_SND_DARLA20 is not set
1681# CONFIG_SND_GINA20 is not set
1682# CONFIG_SND_LAYLA20 is not set
1683# CONFIG_SND_DARLA24 is not set
1684# CONFIG_SND_GINA24 is not set
1685# CONFIG_SND_LAYLA24 is not set
1686# CONFIG_SND_MONA is not set
1687# CONFIG_SND_MIA is not set
1688# CONFIG_SND_ECHO3G is not set
1689# CONFIG_SND_INDIGO is not set
1690# CONFIG_SND_INDIGOIO is not set
1691# CONFIG_SND_INDIGODJ is not set
1692# CONFIG_SND_EMU10K1 is not set
1693# CONFIG_SND_EMU10K1X is not set
1694# CONFIG_SND_ENS1370 is not set
1695# CONFIG_SND_ENS1371 is not set
1696# CONFIG_SND_ES1938 is not set
1697# CONFIG_SND_ES1968 is not set
1698# CONFIG_SND_FM801 is not set
1699CONFIG_SND_HDA_INTEL=y
1700CONFIG_SND_HDA_HWDEP=y
1701CONFIG_SND_HDA_CODEC_REALTEK=y
1702CONFIG_SND_HDA_CODEC_ANALOG=y
1703CONFIG_SND_HDA_CODEC_SIGMATEL=y
1704CONFIG_SND_HDA_CODEC_VIA=y
1705CONFIG_SND_HDA_CODEC_ATIHDMI=y
1706CONFIG_SND_HDA_CODEC_CONEXANT=y
1707CONFIG_SND_HDA_CODEC_CMEDIA=y
1708CONFIG_SND_HDA_CODEC_SI3054=y
1709CONFIG_SND_HDA_GENERIC=y
1710CONFIG_SND_HDA_POWER_SAVE=y
1711CONFIG_SND_HDA_POWER_SAVE_DEFAULT=0
1712# CONFIG_SND_HDSP is not set
1713# CONFIG_SND_HDSPM is not set
1714# CONFIG_SND_HIFIER is not set
1715# CONFIG_SND_ICE1712 is not set
1716# CONFIG_SND_ICE1724 is not set
1717CONFIG_SND_INTEL8X0=y
1718# CONFIG_SND_INTEL8X0M is not set
1719# CONFIG_SND_KORG1212 is not set
1720# CONFIG_SND_MAESTRO3 is not set
1721# CONFIG_SND_MIXART is not set
1722# CONFIG_SND_NM256 is not set
1723# CONFIG_SND_PCXHR is not set
1724# CONFIG_SND_RIPTIDE is not set
1725# CONFIG_SND_RME32 is not set
1726# CONFIG_SND_RME96 is not set
1727# CONFIG_SND_RME9652 is not set
1728# CONFIG_SND_SIS7019 is not set
1729# CONFIG_SND_SONICVIBES is not set
1730# CONFIG_SND_TRIDENT is not set
1731# CONFIG_SND_VIA82XX is not set
1732# CONFIG_SND_VIA82XX_MODEM is not set
1733# CONFIG_SND_VIRTUOSO is not set
1734# CONFIG_SND_VX222 is not set
1735# CONFIG_SND_YMFPCI is not set
1736CONFIG_SND_USB=y
1737CONFIG_SND_USB_AUDIO=m
1738CONFIG_SND_USB_USX2Y=m
1739CONFIG_SND_USB_CAIAQ=m
1740CONFIG_SND_USB_CAIAQ_INPUT=y
1741# CONFIG_SND_SOC is not set
1742# CONFIG_SOUND_PRIME is not set
1743CONFIG_AC97_BUS=y
1744CONFIG_HID_SUPPORT=y
1745CONFIG_HID=y
1746CONFIG_HID_DEBUG=y
1747CONFIG_HIDRAW=y
1748
1749#
1750# USB Input Devices
1751#
1752CONFIG_USB_HID=y
1753CONFIG_USB_HIDINPUT_POWERBOOK=y
1754CONFIG_HID_FF=y
1755CONFIG_HID_PID=y
1756CONFIG_LOGITECH_FF=y
1757# CONFIG_LOGIRUMBLEPAD2_FF is not set
1758CONFIG_PANTHERLORD_FF=y
1759CONFIG_THRUSTMASTER_FF=y
1760CONFIG_ZEROPLUS_FF=y
1761CONFIG_USB_HIDDEV=y
1762CONFIG_USB_SUPPORT=y
1763CONFIG_USB_ARCH_HAS_HCD=y
1764CONFIG_USB_ARCH_HAS_OHCI=y
1765CONFIG_USB_ARCH_HAS_EHCI=y
1766CONFIG_USB=y
1767# CONFIG_USB_DEBUG is not set
1768CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
1769
1770#
1771# Miscellaneous USB options
1772#
1773CONFIG_USB_DEVICEFS=y
1774# CONFIG_USB_DEVICE_CLASS is not set
1775# CONFIG_USB_DYNAMIC_MINORS is not set
1776CONFIG_USB_SUSPEND=y
1777# CONFIG_USB_OTG is not set
1778
1779#
1780# USB Host Controller Drivers
1781#
1782# CONFIG_USB_C67X00_HCD is not set
1783CONFIG_USB_EHCI_HCD=y
1784CONFIG_USB_EHCI_ROOT_HUB_TT=y
1785CONFIG_USB_EHCI_TT_NEWSCHED=y
1786CONFIG_USB_ISP116X_HCD=m
1787# CONFIG_USB_ISP1760_HCD is not set
1788CONFIG_USB_OHCI_HCD=y
1789# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
1790# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
1791CONFIG_USB_OHCI_LITTLE_ENDIAN=y
1792CONFIG_USB_UHCI_HCD=y
1793CONFIG_USB_U132_HCD=m
1794CONFIG_USB_SL811_HCD=m
1795# CONFIG_USB_R8A66597_HCD is not set
1796
1797#
1798# USB Device Class drivers
1799#
1800CONFIG_USB_ACM=m
1801CONFIG_USB_PRINTER=m
1802# CONFIG_USB_WDM is not set
1803
1804#
1805# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
1806#
1807
1808#
1809# may also be needed; see USB_STORAGE Help for more information
1810#
1811CONFIG_USB_STORAGE=y
1812# CONFIG_USB_STORAGE_DEBUG is not set
1813CONFIG_USB_STORAGE_DATAFAB=y
1814CONFIG_USB_STORAGE_FREECOM=y
1815CONFIG_USB_STORAGE_ISD200=y
1816CONFIG_USB_STORAGE_DPCM=y
1817CONFIG_USB_STORAGE_USBAT=y
1818CONFIG_USB_STORAGE_SDDR09=y
1819CONFIG_USB_STORAGE_SDDR55=y
1820CONFIG_USB_STORAGE_JUMPSHOT=y
1821CONFIG_USB_STORAGE_ALAUDA=y
1822# CONFIG_USB_STORAGE_ONETOUCH is not set
1823CONFIG_USB_STORAGE_KARMA=y
1824# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
1825# CONFIG_USB_LIBUSUAL is not set
1826
1827#
1828# USB Imaging devices
1829#
1830CONFIG_USB_MDC800=m
1831CONFIG_USB_MICROTEK=m
1832CONFIG_USB_MON=y
1833
1834#
1835# USB port drivers
1836#
1837CONFIG_USB_SERIAL=m
1838CONFIG_USB_EZUSB=y
1839CONFIG_USB_SERIAL_GENERIC=y
1840CONFIG_USB_SERIAL_AIRCABLE=m
1841CONFIG_USB_SERIAL_ARK3116=m
1842CONFIG_USB_SERIAL_BELKIN=m
1843CONFIG_USB_SERIAL_CH341=m
1844CONFIG_USB_SERIAL_WHITEHEAT=m
1845CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
1846CONFIG_USB_SERIAL_CP2101=m
1847CONFIG_USB_SERIAL_CYPRESS_M8=m
1848CONFIG_USB_SERIAL_EMPEG=m
1849CONFIG_USB_SERIAL_FTDI_SIO=m
1850CONFIG_USB_SERIAL_FUNSOFT=m
1851CONFIG_USB_SERIAL_VISOR=m
1852CONFIG_USB_SERIAL_IPAQ=m
1853CONFIG_USB_SERIAL_IR=m
1854CONFIG_USB_SERIAL_EDGEPORT=m
1855CONFIG_USB_SERIAL_EDGEPORT_TI=m
1856CONFIG_USB_SERIAL_GARMIN=m
1857CONFIG_USB_SERIAL_IPW=m
1858CONFIG_USB_SERIAL_IUU=m
1859CONFIG_USB_SERIAL_KEYSPAN_PDA=m
1860CONFIG_USB_SERIAL_KEYSPAN=m
1861CONFIG_USB_SERIAL_KEYSPAN_MPR=y
1862CONFIG_USB_SERIAL_KEYSPAN_USA28=y
1863CONFIG_USB_SERIAL_KEYSPAN_USA28X=y
1864CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y
1865CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y
1866CONFIG_USB_SERIAL_KEYSPAN_USA19=y
1867CONFIG_USB_SERIAL_KEYSPAN_USA18X=y
1868CONFIG_USB_SERIAL_KEYSPAN_USA19W=y
1869CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y
1870CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y
1871CONFIG_USB_SERIAL_KEYSPAN_USA49W=y
1872CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
1873CONFIG_USB_SERIAL_KLSI=m
1874CONFIG_USB_SERIAL_KOBIL_SCT=m
1875CONFIG_USB_SERIAL_MCT_U232=m
1876CONFIG_USB_SERIAL_MOS7720=m
1877CONFIG_USB_SERIAL_MOS7840=m
1878# CONFIG_USB_SERIAL_MOTOROLA is not set
1879CONFIG_USB_SERIAL_NAVMAN=m
1880CONFIG_USB_SERIAL_PL2303=m
1881CONFIG_USB_SERIAL_OTI6858=m
1882# CONFIG_USB_SERIAL_SPCP8X5 is not set
1883CONFIG_USB_SERIAL_HP4X=m
1884CONFIG_USB_SERIAL_SAFE=m
1885CONFIG_USB_SERIAL_SAFE_PADDED=y
1886CONFIG_USB_SERIAL_SIERRAWIRELESS=m
1887CONFIG_USB_SERIAL_TI=m
1888CONFIG_USB_SERIAL_CYBERJACK=m
1889CONFIG_USB_SERIAL_XIRCOM=m
1890CONFIG_USB_SERIAL_OPTION=m
1891CONFIG_USB_SERIAL_OMNINET=m
1892CONFIG_USB_SERIAL_DEBUG=m
1893
1894#
1895# USB Miscellaneous drivers
1896#
1897CONFIG_USB_EMI62=m
1898CONFIG_USB_EMI26=m
1899CONFIG_USB_ADUTUX=m
1900CONFIG_USB_AUERSWALD=m
1901# CONFIG_USB_RIO500 is not set
1902CONFIG_USB_LEGOTOWER=m
1903CONFIG_USB_LCD=m
1904CONFIG_USB_BERRY_CHARGE=m
1905CONFIG_USB_LED=m
1906# CONFIG_USB_CYPRESS_CY7C63 is not set
1907# CONFIG_USB_CYTHERM is not set
1908CONFIG_USB_PHIDGET=m
1909CONFIG_USB_PHIDGETKIT=m
1910CONFIG_USB_PHIDGETMOTORCONTROL=m
1911CONFIG_USB_PHIDGETSERVO=m
1912CONFIG_USB_IDMOUSE=m
1913CONFIG_USB_FTDI_ELAN=m
1914CONFIG_USB_APPLEDISPLAY=m
1915CONFIG_USB_SISUSBVGA=m
1916CONFIG_USB_SISUSBVGA_CON=y
1917CONFIG_USB_LD=m
1918CONFIG_USB_TRANCEVIBRATOR=m
1919CONFIG_USB_IOWARRIOR=m
1920# CONFIG_USB_TEST is not set
1921# CONFIG_USB_ISIGHTFW is not set
1922# CONFIG_USB_GADGET is not set
1923CONFIG_MMC=m
1924# CONFIG_MMC_DEBUG is not set
1925# CONFIG_MMC_UNSAFE_RESUME is not set
1926
1927#
1928# MMC/SD Card Drivers
1929#
1930CONFIG_MMC_BLOCK=m
1931CONFIG_MMC_BLOCK_BOUNCE=y
1932CONFIG_SDIO_UART=m
1933# CONFIG_MMC_TEST is not set
1934
1935#
1936# MMC/SD Host Controller Drivers
1937#
1938CONFIG_MMC_SDHCI=m
1939# CONFIG_MMC_SDHCI_PCI is not set
1940CONFIG_MMC_WBSD=m
1941CONFIG_MMC_TIFM_SD=m
1942CONFIG_MEMSTICK=m
1943CONFIG_MEMSTICK_DEBUG=y
1944
1945#
1946# MemoryStick drivers
1947#
1948# CONFIG_MEMSTICK_UNSAFE_RESUME is not set
1949CONFIG_MSPRO_BLOCK=m
1950
1951#
1952# MemoryStick Host Controller Drivers
1953#
1954# CONFIG_MEMSTICK_TIFM_MS is not set
1955# CONFIG_MEMSTICK_JMICRON_38X is not set
1956CONFIG_NEW_LEDS=y
1957CONFIG_LEDS_CLASS=m
1958
1959#
1960# LED drivers
1961#
1962# CONFIG_LEDS_PCA9532 is not set
1963# CONFIG_LEDS_CLEVO_MAIL is not set
1964# CONFIG_LEDS_PCA955X is not set
1965
1966#
1967# LED Triggers
1968#
1969CONFIG_LEDS_TRIGGERS=y
1970# CONFIG_LEDS_TRIGGER_TIMER is not set
1971# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
1972# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
1973# CONFIG_ACCESSIBILITY is not set
1974# CONFIG_INFINIBAND is not set
1975# CONFIG_EDAC is not set
1976CONFIG_RTC_LIB=y
1977CONFIG_RTC_CLASS=y
1978# CONFIG_RTC_HCTOSYS is not set
1979# CONFIG_RTC_DEBUG is not set
1980
1981#
1982# RTC interfaces
1983#
1984CONFIG_RTC_INTF_SYSFS=y
1985CONFIG_RTC_INTF_PROC=y
1986CONFIG_RTC_INTF_DEV=y
1987# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
1988# CONFIG_RTC_DRV_TEST is not set
1989
1990#
1991# I2C RTC drivers
1992#
1993# CONFIG_RTC_DRV_DS1307 is not set
1994# CONFIG_RTC_DRV_DS1374 is not set
1995# CONFIG_RTC_DRV_DS1672 is not set
1996# CONFIG_RTC_DRV_MAX6900 is not set
1997# CONFIG_RTC_DRV_RS5C372 is not set
1998# CONFIG_RTC_DRV_ISL1208 is not set
1999# CONFIG_RTC_DRV_X1205 is not set
2000# CONFIG_RTC_DRV_PCF8563 is not set
2001# CONFIG_RTC_DRV_PCF8583 is not set
2002# CONFIG_RTC_DRV_M41T80 is not set
2003# CONFIG_RTC_DRV_S35390A is not set
2004# CONFIG_RTC_DRV_FM3130 is not set
2005
2006#
2007# SPI RTC drivers
2008#
2009
2010#
2011# Platform RTC drivers
2012#
2013CONFIG_RTC_DRV_CMOS=y
2014# CONFIG_RTC_DRV_DS1511 is not set
2015# CONFIG_RTC_DRV_DS1553 is not set
2016# CONFIG_RTC_DRV_DS1742 is not set
2017# CONFIG_RTC_DRV_STK17TA8 is not set
2018# CONFIG_RTC_DRV_M48T86 is not set
2019# CONFIG_RTC_DRV_M48T59 is not set
2020# CONFIG_RTC_DRV_V3020 is not set
2021
2022#
2023# on-CPU RTC drivers
2024#
2025# CONFIG_DMADEVICES is not set
2026# CONFIG_UIO is not set
2027
2028#
2029# Firmware Drivers
2030#
2031# CONFIG_EDD is not set
2032CONFIG_FIRMWARE_MEMMAP=y
2033# CONFIG_DELL_RBU is not set
2034# CONFIG_DCDBAS is not set
2035# CONFIG_DMIID is not set
2036# CONFIG_ISCSI_IBFT_FIND is not set
2037
2038#
2039# File systems
2040#
2041# CONFIG_EXT2_FS is not set
2042CONFIG_EXT3_FS=y
2043CONFIG_EXT3_FS_XATTR=y
2044CONFIG_EXT3_FS_POSIX_ACL=y
2045CONFIG_EXT3_FS_SECURITY=y
2046# CONFIG_EXT4DEV_FS is not set
2047CONFIG_JBD=y
2048# CONFIG_JBD_DEBUG is not set
2049CONFIG_FS_MBCACHE=y
2050# CONFIG_REISERFS_FS is not set
2051# CONFIG_JFS_FS is not set
2052CONFIG_FS_POSIX_ACL=y
2053# CONFIG_XFS_FS is not set
2054# CONFIG_OCFS2_FS is not set
2055CONFIG_DNOTIFY=y
2056CONFIG_INOTIFY=y
2057CONFIG_INOTIFY_USER=y
2058CONFIG_QUOTA=y
2059CONFIG_QUOTA_NETLINK_INTERFACE=y
2060# CONFIG_PRINT_QUOTA_WARNING is not set
2061# CONFIG_QFMT_V1 is not set
2062CONFIG_QFMT_V2=y
2063CONFIG_QUOTACTL=y
2064# CONFIG_AUTOFS_FS is not set
2065# CONFIG_AUTOFS4_FS is not set
2066CONFIG_FUSE_FS=m
2067CONFIG_GENERIC_ACL=y
2068
2069#
2070# CD-ROM/DVD Filesystems
2071#
2072CONFIG_ISO9660_FS=y
2073CONFIG_JOLIET=y
2074CONFIG_ZISOFS=y
2075CONFIG_UDF_FS=m
2076CONFIG_UDF_NLS=y
2077
2078#
2079# DOS/FAT/NT Filesystems
2080#
2081CONFIG_FAT_FS=y
2082CONFIG_MSDOS_FS=y
2083CONFIG_VFAT_FS=y
2084CONFIG_FAT_DEFAULT_CODEPAGE=437
2085CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
2086# CONFIG_NTFS_FS is not set
2087
2088#
2089# Pseudo filesystems
2090#
2091CONFIG_PROC_FS=y
2092CONFIG_PROC_KCORE=y
2093CONFIG_PROC_VMCORE=y
2094CONFIG_PROC_SYSCTL=y
2095CONFIG_SYSFS=y
2096CONFIG_TMPFS=y
2097CONFIG_TMPFS_POSIX_ACL=y
2098CONFIG_HUGETLBFS=y
2099CONFIG_HUGETLB_PAGE=y
2100CONFIG_CONFIGFS_FS=m
2101
2102#
2103# Layered filesystems
2104#
2105# CONFIG_ECRYPT_FS is not set
2106CONFIG_UNION_FS=y
2107# CONFIG_UNION_FS_XATTR is not set
2108# CONFIG_UNION_FS_DEBUG is not set
2109
2110#
2111# Miscellaneous filesystems
2112#
2113# CONFIG_ADFS_FS is not set
2114# CONFIG_AFFS_FS is not set
2115# CONFIG_HFS_FS is not set
2116# CONFIG_HFSPLUS_FS is not set
2117# CONFIG_BEFS_FS is not set
2118# CONFIG_BFS_FS is not set
2119# CONFIG_EFS_FS is not set
2120# CONFIG_CRAMFS is not set
2121CONFIG_SQUASHFS=y
2122# CONFIG_SQUASHFS_EMBEDDED is not set
2123CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
2124# CONFIG_VXFS_FS is not set
2125# CONFIG_MINIX_FS is not set
2126# CONFIG_OMFS_FS is not set
2127# CONFIG_HPFS_FS is not set
2128# CONFIG_QNX4FS_FS is not set
2129# CONFIG_ROMFS_FS is not set
2130# CONFIG_SYSV_FS is not set
2131# CONFIG_UFS_FS is not set
2132CONFIG_NETWORK_FILESYSTEMS=y
2133# CONFIG_NFS_FS is not set
2134# CONFIG_NFSD is not set
2135# CONFIG_SMB_FS is not set
2136# CONFIG_CIFS is not set
2137# CONFIG_NCP_FS is not set
2138# CONFIG_CODA_FS is not set
2139# CONFIG_AFS_FS is not set
2140
2141#
2142# Partition Types
2143#
2144CONFIG_PARTITION_ADVANCED=y
2145# CONFIG_ACORN_PARTITION is not set
2146CONFIG_OSF_PARTITION=y
2147CONFIG_AMIGA_PARTITION=y
2148# CONFIG_ATARI_PARTITION is not set
2149CONFIG_MAC_PARTITION=y
2150CONFIG_MSDOS_PARTITION=y
2151CONFIG_BSD_DISKLABEL=y
2152CONFIG_MINIX_SUBPARTITION=y
2153CONFIG_SOLARIS_X86_PARTITION=y
2154CONFIG_UNIXWARE_DISKLABEL=y
2155# CONFIG_LDM_PARTITION is not set
2156CONFIG_SGI_PARTITION=y
2157# CONFIG_ULTRIX_PARTITION is not set
2158CONFIG_SUN_PARTITION=y
2159CONFIG_KARMA_PARTITION=y
2160CONFIG_EFI_PARTITION=y
2161# CONFIG_SYSV68_PARTITION is not set
2162CONFIG_NLS=y
2163CONFIG_NLS_DEFAULT="utf8"
2164CONFIG_NLS_CODEPAGE_437=y
2165CONFIG_NLS_CODEPAGE_737=m
2166CONFIG_NLS_CODEPAGE_775=m
2167CONFIG_NLS_CODEPAGE_850=m
2168CONFIG_NLS_CODEPAGE_852=m
2169CONFIG_NLS_CODEPAGE_855=m
2170CONFIG_NLS_CODEPAGE_857=m
2171CONFIG_NLS_CODEPAGE_860=m
2172CONFIG_NLS_CODEPAGE_861=m
2173CONFIG_NLS_CODEPAGE_862=m
2174CONFIG_NLS_CODEPAGE_863=m
2175CONFIG_NLS_CODEPAGE_864=m
2176CONFIG_NLS_CODEPAGE_865=m
2177CONFIG_NLS_CODEPAGE_866=m
2178CONFIG_NLS_CODEPAGE_869=m
2179CONFIG_NLS_CODEPAGE_936=m
2180CONFIG_NLS_CODEPAGE_950=m
2181CONFIG_NLS_CODEPAGE_932=m
2182CONFIG_NLS_CODEPAGE_949=m
2183CONFIG_NLS_CODEPAGE_874=m
2184CONFIG_NLS_ISO8859_8=m
2185CONFIG_NLS_CODEPAGE_1250=m
2186CONFIG_NLS_CODEPAGE_1251=m
2187CONFIG_NLS_ASCII=y
2188CONFIG_NLS_ISO8859_1=m
2189CONFIG_NLS_ISO8859_2=m
2190CONFIG_NLS_ISO8859_3=m
2191CONFIG_NLS_ISO8859_4=m
2192CONFIG_NLS_ISO8859_5=m
2193CONFIG_NLS_ISO8859_6=m
2194CONFIG_NLS_ISO8859_7=m
2195CONFIG_NLS_ISO8859_9=m
2196CONFIG_NLS_ISO8859_13=m
2197CONFIG_NLS_ISO8859_14=m
2198CONFIG_NLS_ISO8859_15=m
2199CONFIG_NLS_KOI8_R=m
2200CONFIG_NLS_KOI8_U=m
2201CONFIG_NLS_UTF8=m
2202# CONFIG_DLM is not set
2203
2204#
2205# Kernel hacking
2206#
2207CONFIG_TRACE_IRQFLAGS_SUPPORT=y
2208CONFIG_PRINTK_TIME=y
2209# CONFIG_ENABLE_WARN_DEPRECATED is not set
2210CONFIG_ENABLE_MUST_CHECK=y
2211CONFIG_FRAME_WARN=1024
2212CONFIG_MAGIC_SYSRQ=y
2213CONFIG_UNUSED_SYMBOLS=y
2214CONFIG_DEBUG_FS=y
2215# CONFIG_HEADERS_CHECK is not set
2216CONFIG_DEBUG_KERNEL=y
2217CONFIG_DEBUG_SHIRQ=y
2218CONFIG_DETECT_SOFTLOCKUP=y
2219# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
2220CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
2221CONFIG_SCHED_DEBUG=y
2222CONFIG_SCHEDSTATS=y
2223CONFIG_TIMER_STATS=y
2224# CONFIG_DEBUG_OBJECTS is not set
2225# CONFIG_DEBUG_SLAB is not set
2226# CONFIG_DEBUG_RT_MUTEXES is not set
2227# CONFIG_RT_MUTEX_TESTER is not set
2228# CONFIG_DEBUG_SPINLOCK is not set
2229# CONFIG_DEBUG_MUTEXES is not set
2230# CONFIG_DEBUG_LOCK_ALLOC is not set
2231# CONFIG_PROVE_LOCKING is not set
2232# CONFIG_LOCK_STAT is not set
2233CONFIG_DEBUG_SPINLOCK_SLEEP=y
2234# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
2235CONFIG_STACKTRACE=y
2236# CONFIG_DEBUG_KOBJECT is not set
2237# CONFIG_DEBUG_HIGHMEM is not set
2238CONFIG_DEBUG_BUGVERBOSE=y
2239# CONFIG_DEBUG_INFO is not set
2240# CONFIG_DEBUG_VM is not set
2241# CONFIG_DEBUG_WRITECOUNT is not set
2242CONFIG_DEBUG_MEMORY_INIT=y
2243CONFIG_DEBUG_LIST=y
2244# CONFIG_DEBUG_SG is not set
2245CONFIG_FRAME_POINTER=y
2246CONFIG_BOOT_PRINTK_DELAY=y
2247# CONFIG_RCU_TORTURE_TEST is not set
2248# CONFIG_BACKTRACE_SELF_TEST is not set
2249# CONFIG_FAULT_INJECTION is not set
2250CONFIG_LATENCYTOP=y
2251CONFIG_HAVE_FTRACE=y
2252CONFIG_HAVE_DYNAMIC_FTRACE=y
2253CONFIG_TRACING=y
2254# CONFIG_FTRACE is not set
2255# CONFIG_IRQSOFF_TRACER is not set
2256CONFIG_SYSPROF_TRACER=y
2257# CONFIG_SCHED_TRACER is not set
2258# CONFIG_CONTEXT_SWITCH_TRACER is not set
2259# CONFIG_FTRACE_STARTUP_TEST is not set
2260# CONFIG_PROVIDE_OHCI1394_DMA_INIT is not set
2261# CONFIG_SAMPLES is not set
2262CONFIG_HAVE_ARCH_KGDB=y
2263# CONFIG_KGDB is not set
2264# CONFIG_STRICT_DEVMEM is not set
2265CONFIG_X86_VERBOSE_BOOTUP=y
2266CONFIG_EARLY_PRINTK=y
2267# CONFIG_DEBUG_STACKOVERFLOW is not set
2268# CONFIG_DEBUG_STACK_USAGE is not set
2269# CONFIG_DEBUG_PAGEALLOC is not set
2270# CONFIG_DEBUG_PER_CPU_MAPS is not set
2271CONFIG_X86_PTDUMP=y
2272CONFIG_DEBUG_RODATA=y
2273# CONFIG_DEBUG_RODATA_TEST is not set
2274# CONFIG_DEBUG_NX_TEST is not set
2275# CONFIG_4KSTACKS is not set
2276CONFIG_DOUBLEFAULT=y
2277# CONFIG_MMIOTRACE is not set
2278CONFIG_IO_DELAY_TYPE_0X80=0
2279CONFIG_IO_DELAY_TYPE_0XED=1
2280CONFIG_IO_DELAY_TYPE_UDELAY=2
2281CONFIG_IO_DELAY_TYPE_NONE=3
2282CONFIG_IO_DELAY_0X80=y
2283# CONFIG_IO_DELAY_0XED is not set
2284# CONFIG_IO_DELAY_UDELAY is not set
2285# CONFIG_IO_DELAY_NONE is not set
2286CONFIG_DEFAULT_IO_DELAY_TYPE=0
2287CONFIG_DEBUG_BOOT_PARAMS=y
2288# CONFIG_CPA_DEBUG is not set
2289# CONFIG_OPTIMIZE_INLINING is not set
2290
2291#
2292# Security options
2293#
2294CONFIG_KEYS=y
2295CONFIG_KEYS_DEBUG_PROC_KEYS=y
2296CONFIG_SECURITY=y
2297CONFIG_SECURITY_NETWORK=y
2298CONFIG_SECURITY_NETWORK_XFRM=y
2299CONFIG_SECURITY_FILE_CAPABILITIES=y
2300# CONFIG_SECURITY_ROOTPLUG is not set
2301CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=65536
2302# CONFIG_SECURITY_SELINUX is not set
2303# CONFIG_SECURITY_SMACK is not set
2304CONFIG_CRYPTO=y
2305
2306#
2307# Crypto core or helper
2308#
2309CONFIG_CRYPTO_ALGAPI=y
2310CONFIG_CRYPTO_AEAD=m
2311CONFIG_CRYPTO_BLKCIPHER=m
2312CONFIG_CRYPTO_HASH=y
2313CONFIG_CRYPTO_MANAGER=y
2314CONFIG_CRYPTO_GF128MUL=m
2315CONFIG_CRYPTO_NULL=m
2316# CONFIG_CRYPTO_CRYPTD is not set
2317CONFIG_CRYPTO_AUTHENC=m
2318CONFIG_CRYPTO_TEST=m
2319
2320#
2321# Authenticated Encryption with Associated Data
2322#
2323CONFIG_CRYPTO_CCM=m
2324CONFIG_CRYPTO_GCM=m
2325CONFIG_CRYPTO_SEQIV=m
2326
2327#
2328# Block modes
2329#
2330CONFIG_CRYPTO_CBC=m
2331CONFIG_CRYPTO_CTR=m
2332# CONFIG_CRYPTO_CTS is not set
2333CONFIG_CRYPTO_ECB=m
2334CONFIG_CRYPTO_LRW=m
2335CONFIG_CRYPTO_PCBC=m
2336CONFIG_CRYPTO_XTS=m
2337
2338#
2339# Hash modes
2340#
2341CONFIG_CRYPTO_HMAC=y
2342CONFIG_CRYPTO_XCBC=m
2343
2344#
2345# Digest
2346#
2347CONFIG_CRYPTO_CRC32C=m
2348CONFIG_CRYPTO_MD4=m
2349CONFIG_CRYPTO_MD5=y
2350CONFIG_CRYPTO_MICHAEL_MIC=m
2351# CONFIG_CRYPTO_RMD128 is not set
2352# CONFIG_CRYPTO_RMD160 is not set
2353# CONFIG_CRYPTO_RMD256 is not set
2354# CONFIG_CRYPTO_RMD320 is not set
2355CONFIG_CRYPTO_SHA1=y
2356CONFIG_CRYPTO_SHA256=m
2357CONFIG_CRYPTO_SHA512=m
2358CONFIG_CRYPTO_TGR192=m
2359CONFIG_CRYPTO_WP512=m
2360
2361#
2362# Ciphers
2363#
2364CONFIG_CRYPTO_AES=m
2365# CONFIG_CRYPTO_AES_586 is not set
2366CONFIG_CRYPTO_ANUBIS=m
2367CONFIG_CRYPTO_ARC4=m
2368CONFIG_CRYPTO_BLOWFISH=m
2369CONFIG_CRYPTO_CAMELLIA=m
2370CONFIG_CRYPTO_CAST5=m
2371CONFIG_CRYPTO_CAST6=m
2372CONFIG_CRYPTO_DES=m
2373CONFIG_CRYPTO_FCRYPT=m
2374CONFIG_CRYPTO_KHAZAD=m
2375CONFIG_CRYPTO_SALSA20=m
2376# CONFIG_CRYPTO_SALSA20_586 is not set
2377CONFIG_CRYPTO_SEED=m
2378CONFIG_CRYPTO_SERPENT=m
2379CONFIG_CRYPTO_TEA=m
2380CONFIG_CRYPTO_TWOFISH=m
2381CONFIG_CRYPTO_TWOFISH_COMMON=m
2382# CONFIG_CRYPTO_TWOFISH_586 is not set
2383
2384#
2385# Compression
2386#
2387CONFIG_CRYPTO_DEFLATE=m
2388# CONFIG_CRYPTO_LZO is not set
2389CONFIG_CRYPTO_HW=y
2390# CONFIG_CRYPTO_DEV_PADLOCK is not set
2391# CONFIG_CRYPTO_DEV_GEODE is not set
2392# CONFIG_CRYPTO_DEV_HIFN_795X is not set
2393CONFIG_HAVE_KVM=y
2394# CONFIG_VIRTUALIZATION is not set
2395
2396#
2397# Library routines
2398#
2399CONFIG_BITREVERSE=y
2400CONFIG_GENERIC_FIND_FIRST_BIT=y
2401CONFIG_GENERIC_FIND_NEXT_BIT=y
2402CONFIG_CRC_CCITT=m
2403CONFIG_CRC16=m
2404CONFIG_CRC_T10DIF=y
2405CONFIG_CRC_ITU_T=m
2406CONFIG_CRC32=y
2407# CONFIG_CRC7 is not set
2408CONFIG_LIBCRC32C=m
2409CONFIG_AUDIT_GENERIC=y
2410CONFIG_ZLIB_INFLATE=y
2411CONFIG_ZLIB_DEFLATE=m
2412CONFIG_TEXTSEARCH=y
2413CONFIG_TEXTSEARCH_KMP=m
2414CONFIG_TEXTSEARCH_BM=m
2415CONFIG_TEXTSEARCH_FSM=m
2416CONFIG_PLIST=y
2417CONFIG_HAS_IOMEM=y
2418CONFIG_HAS_IOPORT=y
2419CONFIG_HAS_DMA=y
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27-rc1/defconfig-netbook b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc1/defconfig-netbook
new file mode 100644
index 0000000000..666a14c7d9
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc1/defconfig-netbook
@@ -0,0 +1,2419 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.27-rc1
4# Wed Oct 1 17:20:02 2008
5#
6# CONFIG_64BIT is not set
7CONFIG_X86_32=y
8# CONFIG_X86_64 is not set
9CONFIG_X86=y
10CONFIG_ARCH_DEFCONFIG="arch/x86/configs/i386_defconfig"
11# CONFIG_GENERIC_LOCKBREAK is not set
12CONFIG_GENERIC_TIME=y
13CONFIG_GENERIC_CMOS_UPDATE=y
14CONFIG_CLOCKSOURCE_WATCHDOG=y
15CONFIG_GENERIC_CLOCKEVENTS=y
16CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
17CONFIG_LOCKDEP_SUPPORT=y
18CONFIG_STACKTRACE_SUPPORT=y
19CONFIG_HAVE_LATENCYTOP_SUPPORT=y
20CONFIG_FAST_CMPXCHG_LOCAL=y
21CONFIG_MMU=y
22CONFIG_ZONE_DMA=y
23CONFIG_GENERIC_ISA_DMA=y
24CONFIG_GENERIC_IOMAP=y
25CONFIG_GENERIC_BUG=y
26CONFIG_GENERIC_HWEIGHT=y
27# CONFIG_GENERIC_GPIO is not set
28CONFIG_ARCH_MAY_HAVE_PC_FDC=y
29# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
30CONFIG_RWSEM_XCHGADD_ALGORITHM=y
31# CONFIG_ARCH_HAS_ILOG2_U32 is not set
32# CONFIG_ARCH_HAS_ILOG2_U64 is not set
33CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
34CONFIG_GENERIC_CALIBRATE_DELAY=y
35# CONFIG_GENERIC_TIME_VSYSCALL is not set
36CONFIG_ARCH_HAS_CPU_RELAX=y
37CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y
38CONFIG_HAVE_SETUP_PER_CPU_AREA=y
39# CONFIG_HAVE_CPUMASK_OF_CPU_MAP is not set
40CONFIG_ARCH_HIBERNATION_POSSIBLE=y
41CONFIG_ARCH_SUSPEND_POSSIBLE=y
42# CONFIG_ZONE_DMA32 is not set
43CONFIG_ARCH_POPULATES_NODE_MAP=y
44# CONFIG_AUDIT_ARCH is not set
45CONFIG_ARCH_SUPPORTS_AOUT=y
46CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING=y
47CONFIG_GENERIC_HARDIRQS=y
48CONFIG_GENERIC_IRQ_PROBE=y
49CONFIG_GENERIC_PENDING_IRQ=y
50CONFIG_X86_SMP=y
51CONFIG_X86_32_SMP=y
52CONFIG_X86_HT=y
53CONFIG_X86_BIOS_REBOOT=y
54CONFIG_X86_TRAMPOLINE=y
55CONFIG_KTIME_SCALAR=y
56CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
57
58#
59# General setup
60#
61CONFIG_EXPERIMENTAL=y
62CONFIG_LOCK_KERNEL=y
63CONFIG_INIT_ENV_ARG_LIMIT=32
64CONFIG_LOCALVERSION="-netbook"
65# CONFIG_LOCALVERSION_AUTO is not set
66CONFIG_SWAP=y
67CONFIG_SYSVIPC=y
68CONFIG_SYSVIPC_SYSCTL=y
69CONFIG_POSIX_MQUEUE=y
70CONFIG_BSD_PROCESS_ACCT=y
71CONFIG_BSD_PROCESS_ACCT_V3=y
72CONFIG_TASKSTATS=y
73CONFIG_TASK_DELAY_ACCT=y
74CONFIG_TASK_XACCT=y
75CONFIG_TASK_IO_ACCOUNTING=y
76CONFIG_AUDIT=y
77CONFIG_AUDITSYSCALL=y
78CONFIG_AUDIT_TREE=y
79CONFIG_IKCONFIG=y
80CONFIG_IKCONFIG_PROC=y
81CONFIG_LOG_BUF_SHIFT=17
82# CONFIG_CGROUPS is not set
83CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y
84# CONFIG_GROUP_SCHED is not set
85# CONFIG_SYSFS_DEPRECATED_V2 is not set
86CONFIG_RELAY=y
87CONFIG_NAMESPACES=y
88# CONFIG_UTS_NS is not set
89# CONFIG_IPC_NS is not set
90CONFIG_USER_NS=y
91# CONFIG_PID_NS is not set
92CONFIG_BLK_DEV_INITRD=y
93CONFIG_INITRAMFS_SOURCE=""
94CONFIG_CC_OPTIMIZE_FOR_SIZE=y
95CONFIG_SYSCTL=y
96# CONFIG_EMBEDDED is not set
97CONFIG_UID16=y
98CONFIG_SYSCTL_SYSCALL=y
99CONFIG_SYSCTL_SYSCALL_CHECK=y
100CONFIG_KALLSYMS=y
101CONFIG_KALLSYMS_ALL=y
102CONFIG_KALLSYMS_EXTRA_PASS=y
103CONFIG_HOTPLUG=y
104CONFIG_PRINTK=y
105CONFIG_BUG=y
106CONFIG_ELF_CORE=y
107CONFIG_PCSPKR_PLATFORM=y
108# CONFIG_COMPAT_BRK is not set
109CONFIG_BASE_FULL=y
110CONFIG_FUTEX=y
111CONFIG_ANON_INODES=y
112CONFIG_EPOLL=y
113CONFIG_SIGNALFD=y
114CONFIG_TIMERFD=y
115CONFIG_EVENTFD=y
116CONFIG_SHMEM=y
117CONFIG_VM_EVENT_COUNTERS=y
118CONFIG_SLAB=y
119# CONFIG_SLUB is not set
120# CONFIG_SLOB is not set
121CONFIG_PROFILING=y
122# CONFIG_MARKERS is not set
123# CONFIG_OPROFILE is not set
124CONFIG_HAVE_OPROFILE=y
125# CONFIG_KPROBES is not set
126CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
127CONFIG_HAVE_IOREMAP_PROT=y
128CONFIG_HAVE_KPROBES=y
129CONFIG_HAVE_KRETPROBES=y
130# CONFIG_HAVE_ARCH_TRACEHOOK is not set
131# CONFIG_HAVE_DMA_ATTRS is not set
132CONFIG_USE_GENERIC_SMP_HELPERS=y
133# CONFIG_HAVE_CLK is not set
134CONFIG_PROC_PAGE_MONITOR=y
135CONFIG_HAVE_GENERIC_DMA_COHERENT=y
136CONFIG_SLABINFO=y
137CONFIG_RT_MUTEXES=y
138# CONFIG_TINY_SHMEM is not set
139CONFIG_BASE_SMALL=0
140CONFIG_MODULES=y
141# CONFIG_MODULE_FORCE_LOAD is not set
142CONFIG_MODULE_UNLOAD=y
143# CONFIG_MODULE_FORCE_UNLOAD is not set
144# CONFIG_MODVERSIONS is not set
145# CONFIG_MODULE_SRCVERSION_ALL is not set
146CONFIG_KMOD=y
147CONFIG_STOP_MACHINE=y
148CONFIG_BLOCK=y
149# CONFIG_LBD is not set
150CONFIG_BLK_DEV_IO_TRACE=y
151# CONFIG_LSF is not set
152CONFIG_BLK_DEV_BSG=y
153# CONFIG_BLK_DEV_INTEGRITY is not set
154
155#
156# IO Schedulers
157#
158CONFIG_IOSCHED_NOOP=y
159# CONFIG_IOSCHED_AS is not set
160# CONFIG_IOSCHED_DEADLINE is not set
161CONFIG_IOSCHED_CFQ=y
162# CONFIG_DEFAULT_AS is not set
163# CONFIG_DEFAULT_DEADLINE is not set
164CONFIG_DEFAULT_CFQ=y
165# CONFIG_DEFAULT_NOOP is not set
166CONFIG_DEFAULT_IOSCHED="cfq"
167CONFIG_CLASSIC_RCU=y
168
169#
170# Processor type and features
171#
172CONFIG_TICK_ONESHOT=y
173CONFIG_NO_HZ=y
174CONFIG_HIGH_RES_TIMERS=y
175CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
176CONFIG_SMP=y
177CONFIG_X86_FIND_SMP_CONFIG=y
178CONFIG_X86_MPPARSE=y
179CONFIG_X86_PC=y
180# CONFIG_X86_ELAN is not set
181# CONFIG_X86_VOYAGER is not set
182# CONFIG_X86_GENERICARCH is not set
183# CONFIG_X86_VSMP is not set
184# CONFIG_X86_RDC321X is not set
185CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
186# CONFIG_PARAVIRT_GUEST is not set
187# CONFIG_MEMTEST is not set
188# CONFIG_M386 is not set
189# CONFIG_M486 is not set
190# CONFIG_M586 is not set
191# CONFIG_M586TSC is not set
192# CONFIG_M586MMX is not set
193CONFIG_M686=y
194# CONFIG_MPENTIUMII is not set
195# CONFIG_MPENTIUMIII is not set
196# CONFIG_MPENTIUMM is not set
197# CONFIG_MPENTIUM4 is not set
198# CONFIG_MK6 is not set
199# CONFIG_MK7 is not set
200# CONFIG_MK8 is not set
201# CONFIG_MCRUSOE is not set
202# CONFIG_MEFFICEON is not set
203# CONFIG_MWINCHIPC6 is not set
204# CONFIG_MWINCHIP2 is not set
205# CONFIG_MWINCHIP3D is not set
206# CONFIG_MGEODEGX1 is not set
207# CONFIG_MGEODE_LX is not set
208# CONFIG_MCYRIXIII is not set
209# CONFIG_MVIAC3_2 is not set
210# CONFIG_MVIAC7 is not set
211# CONFIG_MPSC is not set
212# CONFIG_MCORE2 is not set
213# CONFIG_GENERIC_CPU is not set
214# CONFIG_X86_GENERIC is not set
215CONFIG_X86_CPU=y
216CONFIG_X86_CMPXCHG=y
217CONFIG_X86_L1_CACHE_SHIFT=5
218CONFIG_X86_XADD=y
219# CONFIG_X86_PPRO_FENCE is not set
220CONFIG_X86_WP_WORKS_OK=y
221CONFIG_X86_INVLPG=y
222CONFIG_X86_BSWAP=y
223CONFIG_X86_POPAD_OK=y
224CONFIG_X86_USE_PPRO_CHECKSUM=y
225CONFIG_X86_P6_NOP=y
226CONFIG_X86_TSC=y
227CONFIG_X86_CMOV=y
228CONFIG_X86_MINIMUM_CPU_FAMILY=6
229CONFIG_X86_DEBUGCTLMSR=y
230CONFIG_HPET_TIMER=y
231CONFIG_HPET_EMULATE_RTC=y
232CONFIG_DMI=y
233# CONFIG_IOMMU_HELPER is not set
234CONFIG_NR_CPUS=2
235CONFIG_SCHED_SMT=y
236CONFIG_SCHED_MC=y
237# CONFIG_PREEMPT_NONE is not set
238CONFIG_PREEMPT_VOLUNTARY=y
239# CONFIG_PREEMPT is not set
240CONFIG_X86_LOCAL_APIC=y
241CONFIG_X86_IO_APIC=y
242CONFIG_X86_MCE=y
243# CONFIG_X86_MCE_NONFATAL is not set
244# CONFIG_X86_MCE_P4THERMAL is not set
245CONFIG_VM86=y
246# CONFIG_TOSHIBA is not set
247# CONFIG_I8K is not set
248# CONFIG_X86_REBOOTFIXUPS is not set
249CONFIG_MICROCODE=y
250CONFIG_MICROCODE_OLD_INTERFACE=y
251CONFIG_X86_MSR=y
252CONFIG_X86_CPUID=y
253# CONFIG_NOHIGHMEM is not set
254CONFIG_HIGHMEM4G=y
255# CONFIG_HIGHMEM64G is not set
256CONFIG_PAGE_OFFSET=0xC0000000
257CONFIG_HIGHMEM=y
258CONFIG_NEED_NODE_MEMMAP_SIZE=y
259CONFIG_ARCH_FLATMEM_ENABLE=y
260CONFIG_ARCH_SPARSEMEM_ENABLE=y
261CONFIG_ARCH_SELECT_MEMORY_MODEL=y
262CONFIG_SELECT_MEMORY_MODEL=y
263# CONFIG_FLATMEM_MANUAL is not set
264# CONFIG_DISCONTIGMEM_MANUAL is not set
265CONFIG_SPARSEMEM_MANUAL=y
266CONFIG_SPARSEMEM=y
267CONFIG_HAVE_GET_USER_PAGES_FAST=y
268CONFIG_HAVE_MEMORY_PRESENT=y
269CONFIG_SPARSEMEM_STATIC=y
270# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
271
272#
273# Memory hotplug is currently incompatible with Software Suspend
274#
275CONFIG_PAGEFLAGS_EXTENDED=y
276CONFIG_SPLIT_PTLOCK_CPUS=4
277CONFIG_RESOURCES_64BIT=y
278CONFIG_ZONE_DMA_FLAG=1
279CONFIG_BOUNCE=y
280CONFIG_VIRT_TO_BUS=y
281# CONFIG_HIGHPTE is not set
282# CONFIG_MATH_EMULATION is not set
283CONFIG_MTRR=y
284# CONFIG_MTRR_SANITIZER is not set
285# CONFIG_X86_PAT is not set
286# CONFIG_EFI is not set
287# CONFIG_IRQBALANCE is not set
288# CONFIG_SECCOMP is not set
289# CONFIG_HZ_100 is not set
290# CONFIG_HZ_250 is not set
291# CONFIG_HZ_300 is not set
292CONFIG_HZ_1000=y
293CONFIG_HZ=1000
294CONFIG_SCHED_HRTICK=y
295CONFIG_KEXEC=y
296CONFIG_CRASH_DUMP=y
297# CONFIG_KEXEC_JUMP is not set
298CONFIG_PHYSICAL_START=0x400000
299CONFIG_RELOCATABLE=y
300CONFIG_PHYSICAL_ALIGN=0x200000
301CONFIG_HOTPLUG_CPU=y
302CONFIG_COMPAT_VDSO=y
303CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
304
305#
306# Power management options
307#
308CONFIG_PM=y
309CONFIG_PM_DEBUG=y
310# CONFIG_PM_VERBOSE is not set
311CONFIG_CAN_PM_TRACE=y
312CONFIG_PM_TRACE=y
313CONFIG_PM_TRACE_RTC=y
314CONFIG_PM_SLEEP_SMP=y
315CONFIG_PM_SLEEP=y
316CONFIG_SUSPEND=y
317# CONFIG_PM_TEST_SUSPEND is not set
318CONFIG_SUSPEND_FREEZER=y
319CONFIG_HIBERNATION=y
320CONFIG_PM_STD_PARTITION=""
321CONFIG_ACPI=y
322CONFIG_ACPI_SLEEP=y
323CONFIG_ACPI_PROCFS=y
324CONFIG_ACPI_PROCFS_POWER=y
325CONFIG_ACPI_SYSFS_POWER=y
326CONFIG_ACPI_PROC_EVENT=y
327CONFIG_ACPI_AC=y
328CONFIG_ACPI_BATTERY=m
329CONFIG_ACPI_BUTTON=y
330CONFIG_ACPI_VIDEO=y
331CONFIG_ACPI_FAN=y
332CONFIG_ACPI_DOCK=y
333# CONFIG_ACPI_BAY is not set
334CONFIG_ACPI_PROCESSOR=y
335CONFIG_ACPI_HOTPLUG_CPU=y
336CONFIG_ACPI_THERMAL=y
337CONFIG_ACPI_WMI=m
338CONFIG_ACPI_ASUS=y
339# CONFIG_ACPI_TOSHIBA is not set
340# CONFIG_ACPI_CUSTOM_DSDT is not set
341CONFIG_ACPI_BLACKLIST_YEAR=0
342# CONFIG_ACPI_DEBUG is not set
343CONFIG_ACPI_EC=y
344# CONFIG_ACPI_PCI_SLOT is not set
345CONFIG_ACPI_POWER=y
346CONFIG_ACPI_SYSTEM=y
347CONFIG_X86_PM_TIMER=y
348CONFIG_ACPI_CONTAINER=y
349CONFIG_ACPI_SBS=m
350# CONFIG_APM is not set
351
352#
353# CPU Frequency scaling
354#
355CONFIG_CPU_FREQ=y
356CONFIG_CPU_FREQ_TABLE=y
357CONFIG_CPU_FREQ_DEBUG=y
358CONFIG_CPU_FREQ_STAT=m
359CONFIG_CPU_FREQ_STAT_DETAILS=y
360CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
361# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
362# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
363# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
364# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
365CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
366# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
367CONFIG_CPU_FREQ_GOV_USERSPACE=y
368CONFIG_CPU_FREQ_GOV_ONDEMAND=y
369# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
370
371#
372# CPUFreq processor drivers
373#
374CONFIG_X86_ACPI_CPUFREQ=y
375# CONFIG_X86_POWERNOW_K6 is not set
376# CONFIG_X86_POWERNOW_K7 is not set
377# CONFIG_X86_POWERNOW_K8 is not set
378# CONFIG_X86_GX_SUSPMOD is not set
379# CONFIG_X86_SPEEDSTEP_CENTRINO is not set
380# CONFIG_X86_SPEEDSTEP_ICH is not set
381# CONFIG_X86_SPEEDSTEP_SMI is not set
382# CONFIG_X86_P4_CLOCKMOD is not set
383# CONFIG_X86_CPUFREQ_NFORCE2 is not set
384# CONFIG_X86_LONGRUN is not set
385# CONFIG_X86_LONGHAUL is not set
386# CONFIG_X86_E_POWERSAVER is not set
387
388#
389# shared options
390#
391# CONFIG_X86_ACPI_CPUFREQ_PROC_INTF is not set
392# CONFIG_X86_SPEEDSTEP_LIB is not set
393CONFIG_CPU_IDLE=y
394CONFIG_CPU_IDLE_GOV_LADDER=y
395CONFIG_CPU_IDLE_GOV_MENU=y
396
397#
398# Bus options (PCI etc.)
399#
400CONFIG_PCI=y
401# CONFIG_PCI_GOBIOS is not set
402# CONFIG_PCI_GOMMCONFIG is not set
403# CONFIG_PCI_GODIRECT is not set
404# CONFIG_PCI_GOOLPC is not set
405CONFIG_PCI_GOANY=y
406CONFIG_PCI_BIOS=y
407CONFIG_PCI_DIRECT=y
408CONFIG_PCI_MMCONFIG=y
409CONFIG_PCI_DOMAINS=y
410CONFIG_PCIEPORTBUS=y
411CONFIG_PCIEAER=y
412CONFIG_PCIEASPM=y
413# CONFIG_PCIEASPM_DEBUG is not set
414CONFIG_ARCH_SUPPORTS_MSI=y
415CONFIG_PCI_MSI=y
416CONFIG_PCI_LEGACY=y
417# CONFIG_PCI_DEBUG is not set
418CONFIG_HT_IRQ=y
419CONFIG_ISA_DMA_API=y
420# CONFIG_ISA is not set
421# CONFIG_MCA is not set
422# CONFIG_SCx200 is not set
423# CONFIG_OLPC is not set
424CONFIG_K8_NB=y
425# CONFIG_PCCARD is not set
426# CONFIG_HOTPLUG_PCI is not set
427
428#
429# Executable file formats / Emulations
430#
431CONFIG_BINFMT_ELF=y
432# CONFIG_BINFMT_AOUT is not set
433CONFIG_BINFMT_MISC=y
434
435#
436# Networking
437#
438CONFIG_NET=y
439
440#
441# Networking options
442#
443CONFIG_PACKET=y
444CONFIG_PACKET_MMAP=y
445CONFIG_UNIX=y
446CONFIG_XFRM=y
447CONFIG_XFRM_USER=y
448CONFIG_XFRM_SUB_POLICY=y
449CONFIG_XFRM_MIGRATE=y
450CONFIG_XFRM_STATISTICS=y
451CONFIG_XFRM_IPCOMP=m
452CONFIG_NET_KEY=m
453CONFIG_NET_KEY_MIGRATE=y
454CONFIG_INET=y
455CONFIG_IP_MULTICAST=y
456# CONFIG_IP_ADVANCED_ROUTER is not set
457CONFIG_IP_FIB_HASH=y
458# CONFIG_IP_PNP is not set
459# CONFIG_NET_IPIP is not set
460# CONFIG_NET_IPGRE is not set
461CONFIG_IP_MROUTE=y
462CONFIG_IP_PIMSM_V1=y
463CONFIG_IP_PIMSM_V2=y
464# CONFIG_ARPD is not set
465CONFIG_SYN_COOKIES=y
466CONFIG_INET_AH=m
467CONFIG_INET_ESP=m
468CONFIG_INET_IPCOMP=m
469CONFIG_INET_XFRM_TUNNEL=m
470CONFIG_INET_TUNNEL=m
471CONFIG_INET_XFRM_MODE_TRANSPORT=m
472CONFIG_INET_XFRM_MODE_TUNNEL=m
473CONFIG_INET_XFRM_MODE_BEET=m
474CONFIG_INET_LRO=y
475CONFIG_INET_DIAG=m
476CONFIG_INET_TCP_DIAG=m
477CONFIG_TCP_CONG_ADVANCED=y
478CONFIG_TCP_CONG_BIC=m
479CONFIG_TCP_CONG_CUBIC=y
480# CONFIG_TCP_CONG_WESTWOOD is not set
481# CONFIG_TCP_CONG_HTCP is not set
482# CONFIG_TCP_CONG_HSTCP is not set
483# CONFIG_TCP_CONG_HYBLA is not set
484# CONFIG_TCP_CONG_VEGAS is not set
485# CONFIG_TCP_CONG_SCALABLE is not set
486# CONFIG_TCP_CONG_LP is not set
487# CONFIG_TCP_CONG_VENO is not set
488# CONFIG_TCP_CONG_YEAH is not set
489# CONFIG_TCP_CONG_ILLINOIS is not set
490# CONFIG_DEFAULT_BIC is not set
491CONFIG_DEFAULT_CUBIC=y
492# CONFIG_DEFAULT_HTCP is not set
493# CONFIG_DEFAULT_VEGAS is not set
494# CONFIG_DEFAULT_WESTWOOD is not set
495# CONFIG_DEFAULT_RENO is not set
496CONFIG_DEFAULT_TCP_CONG="cubic"
497CONFIG_TCP_MD5SIG=y
498# CONFIG_IP_VS is not set
499CONFIG_IPV6=y
500CONFIG_IPV6_PRIVACY=y
501CONFIG_IPV6_ROUTER_PREF=y
502CONFIG_IPV6_ROUTE_INFO=y
503CONFIG_IPV6_OPTIMISTIC_DAD=y
504CONFIG_INET6_AH=m
505CONFIG_INET6_ESP=m
506CONFIG_INET6_IPCOMP=m
507CONFIG_IPV6_MIP6=m
508CONFIG_INET6_XFRM_TUNNEL=m
509CONFIG_INET6_TUNNEL=m
510CONFIG_INET6_XFRM_MODE_TRANSPORT=m
511CONFIG_INET6_XFRM_MODE_TUNNEL=m
512CONFIG_INET6_XFRM_MODE_BEET=m
513CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
514CONFIG_IPV6_SIT=m
515CONFIG_IPV6_NDISC_NODETYPE=y
516CONFIG_IPV6_TUNNEL=m
517CONFIG_IPV6_MULTIPLE_TABLES=y
518CONFIG_IPV6_SUBTREES=y
519# CONFIG_IPV6_MROUTE is not set
520CONFIG_NETLABEL=y
521CONFIG_NETWORK_SECMARK=y
522CONFIG_NETFILTER=y
523# CONFIG_NETFILTER_DEBUG is not set
524CONFIG_NETFILTER_ADVANCED=y
525
526#
527# Core Netfilter Configuration
528#
529CONFIG_NETFILTER_NETLINK=m
530CONFIG_NETFILTER_NETLINK_QUEUE=m
531CONFIG_NETFILTER_NETLINK_LOG=m
532CONFIG_NF_CONNTRACK=y
533CONFIG_NF_CT_ACCT=y
534CONFIG_NF_CONNTRACK_MARK=y
535CONFIG_NF_CONNTRACK_SECMARK=y
536CONFIG_NF_CONNTRACK_EVENTS=y
537# CONFIG_NF_CT_PROTO_DCCP is not set
538CONFIG_NF_CT_PROTO_GRE=m
539CONFIG_NF_CT_PROTO_SCTP=m
540CONFIG_NF_CT_PROTO_UDPLITE=m
541CONFIG_NF_CONNTRACK_AMANDA=m
542CONFIG_NF_CONNTRACK_FTP=m
543CONFIG_NF_CONNTRACK_H323=m
544CONFIG_NF_CONNTRACK_IRC=m
545CONFIG_NF_CONNTRACK_NETBIOS_NS=m
546CONFIG_NF_CONNTRACK_PPTP=m
547CONFIG_NF_CONNTRACK_SANE=m
548CONFIG_NF_CONNTRACK_SIP=m
549CONFIG_NF_CONNTRACK_TFTP=m
550CONFIG_NF_CT_NETLINK=m
551CONFIG_NETFILTER_XTABLES=y
552CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
553CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
554CONFIG_NETFILTER_XT_TARGET_DSCP=m
555CONFIG_NETFILTER_XT_TARGET_MARK=m
556CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
557CONFIG_NETFILTER_XT_TARGET_NFLOG=m
558CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
559CONFIG_NETFILTER_XT_TARGET_RATEEST=m
560CONFIG_NETFILTER_XT_TARGET_TRACE=m
561CONFIG_NETFILTER_XT_TARGET_SECMARK=m
562CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
563CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
564CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
565CONFIG_NETFILTER_XT_MATCH_COMMENT=m
566CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
567CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
568CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
569CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
570# CONFIG_NETFILTER_XT_MATCH_DCCP is not set
571CONFIG_NETFILTER_XT_MATCH_DSCP=m
572CONFIG_NETFILTER_XT_MATCH_ESP=m
573CONFIG_NETFILTER_XT_MATCH_HELPER=m
574CONFIG_NETFILTER_XT_MATCH_IPRANGE=m
575CONFIG_NETFILTER_XT_MATCH_LENGTH=m
576CONFIG_NETFILTER_XT_MATCH_LIMIT=m
577CONFIG_NETFILTER_XT_MATCH_MAC=m
578CONFIG_NETFILTER_XT_MATCH_MARK=m
579CONFIG_NETFILTER_XT_MATCH_OWNER=m
580CONFIG_NETFILTER_XT_MATCH_POLICY=m
581CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
582CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
583CONFIG_NETFILTER_XT_MATCH_QUOTA=m
584CONFIG_NETFILTER_XT_MATCH_RATEEST=m
585CONFIG_NETFILTER_XT_MATCH_REALM=m
586CONFIG_NETFILTER_XT_MATCH_SCTP=m
587CONFIG_NETFILTER_XT_MATCH_STATE=y
588CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
589CONFIG_NETFILTER_XT_MATCH_STRING=m
590CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
591CONFIG_NETFILTER_XT_MATCH_TIME=m
592CONFIG_NETFILTER_XT_MATCH_U32=m
593CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
594
595#
596# IP: Netfilter Configuration
597#
598CONFIG_NF_CONNTRACK_IPV4=y
599# CONFIG_NF_CONNTRACK_PROC_COMPAT is not set
600CONFIG_IP_NF_QUEUE=m
601CONFIG_IP_NF_IPTABLES=y
602CONFIG_IP_NF_MATCH_RECENT=m
603CONFIG_IP_NF_MATCH_ECN=m
604CONFIG_IP_NF_MATCH_AH=m
605CONFIG_IP_NF_MATCH_TTL=m
606CONFIG_IP_NF_MATCH_ADDRTYPE=m
607CONFIG_IP_NF_FILTER=y
608CONFIG_IP_NF_TARGET_REJECT=y
609CONFIG_IP_NF_TARGET_LOG=m
610CONFIG_IP_NF_TARGET_ULOG=m
611CONFIG_NF_NAT=m
612CONFIG_NF_NAT_NEEDED=y
613CONFIG_IP_NF_TARGET_MASQUERADE=m
614CONFIG_IP_NF_TARGET_REDIRECT=m
615CONFIG_IP_NF_TARGET_NETMAP=m
616CONFIG_NF_NAT_SNMP_BASIC=m
617CONFIG_NF_NAT_PROTO_GRE=m
618CONFIG_NF_NAT_PROTO_UDPLITE=m
619CONFIG_NF_NAT_PROTO_SCTP=m
620CONFIG_NF_NAT_FTP=m
621CONFIG_NF_NAT_IRC=m
622CONFIG_NF_NAT_TFTP=m
623CONFIG_NF_NAT_AMANDA=m
624CONFIG_NF_NAT_PPTP=m
625CONFIG_NF_NAT_H323=m
626CONFIG_NF_NAT_SIP=m
627CONFIG_IP_NF_MANGLE=m
628CONFIG_IP_NF_TARGET_ECN=m
629CONFIG_IP_NF_TARGET_TTL=m
630CONFIG_IP_NF_TARGET_CLUSTERIP=m
631CONFIG_IP_NF_RAW=m
632# CONFIG_IP_NF_SECURITY is not set
633CONFIG_IP_NF_ARPTABLES=m
634CONFIG_IP_NF_ARPFILTER=m
635CONFIG_IP_NF_ARP_MANGLE=m
636
637#
638# IPv6: Netfilter Configuration
639#
640CONFIG_NF_CONNTRACK_IPV6=y
641CONFIG_IP6_NF_QUEUE=m
642CONFIG_IP6_NF_IPTABLES=y
643CONFIG_IP6_NF_MATCH_RT=m
644CONFIG_IP6_NF_MATCH_OPTS=m
645CONFIG_IP6_NF_MATCH_FRAG=m
646CONFIG_IP6_NF_MATCH_HL=m
647CONFIG_IP6_NF_MATCH_IPV6HEADER=m
648CONFIG_IP6_NF_MATCH_AH=m
649CONFIG_IP6_NF_MATCH_MH=m
650CONFIG_IP6_NF_MATCH_EUI64=m
651CONFIG_IP6_NF_FILTER=y
652CONFIG_IP6_NF_TARGET_LOG=m
653CONFIG_IP6_NF_TARGET_REJECT=y
654CONFIG_IP6_NF_MANGLE=m
655CONFIG_IP6_NF_TARGET_HL=m
656CONFIG_IP6_NF_RAW=m
657# CONFIG_IP6_NF_SECURITY is not set
658# CONFIG_IP_DCCP is not set
659# CONFIG_IP_SCTP is not set
660# CONFIG_TIPC is not set
661# CONFIG_ATM is not set
662# CONFIG_BRIDGE is not set
663# CONFIG_VLAN_8021Q is not set
664# CONFIG_DECNET is not set
665# CONFIG_LLC2 is not set
666# CONFIG_IPX is not set
667# CONFIG_ATALK is not set
668# CONFIG_X25 is not set
669# CONFIG_LAPB is not set
670# CONFIG_ECONET is not set
671# CONFIG_WAN_ROUTER is not set
672# CONFIG_NET_SCHED is not set
673CONFIG_NET_CLS_ROUTE=y
674
675#
676# Network testing
677#
678# CONFIG_NET_PKTGEN is not set
679# CONFIG_HAMRADIO is not set
680# CONFIG_CAN is not set
681# CONFIG_IRDA is not set
682CONFIG_BT=m
683CONFIG_BT_L2CAP=m
684CONFIG_BT_SCO=m
685CONFIG_BT_RFCOMM=m
686CONFIG_BT_RFCOMM_TTY=y
687CONFIG_BT_BNEP=m
688# CONFIG_BT_BNEP_MC_FILTER is not set
689# CONFIG_BT_BNEP_PROTO_FILTER is not set
690# CONFIG_BT_HIDP is not set
691
692#
693# Bluetooth device drivers
694#
695CONFIG_BT_HCIUSB=m
696CONFIG_BT_HCIUSB_SCO=y
697CONFIG_BT_HCIBTSDIO=m
698CONFIG_BT_HCIUART=m
699CONFIG_BT_HCIUART_H4=y
700CONFIG_BT_HCIUART_BCSP=y
701CONFIG_BT_HCIUART_LL=y
702CONFIG_BT_HCIBCM203X=m
703CONFIG_BT_HCIBPA10X=m
704CONFIG_BT_HCIBFUSB=m
705CONFIG_BT_HCIVHCI=m
706# CONFIG_AF_RXRPC is not set
707CONFIG_FIB_RULES=y
708
709#
710# Wireless
711#
712CONFIG_CFG80211=m
713CONFIG_NL80211=y
714CONFIG_WIRELESS_EXT=y
715# CONFIG_WIRELESS_EXT_SYSFS is not set
716CONFIG_MAC80211=m
717
718#
719# Rate control algorithm selection
720#
721CONFIG_MAC80211_RC_PID=y
722CONFIG_MAC80211_RC_DEFAULT_PID=y
723CONFIG_MAC80211_RC_DEFAULT="pid"
724CONFIG_MAC80211_MESH=y
725CONFIG_MAC80211_LEDS=y
726CONFIG_MAC80211_DEBUGFS=y
727# CONFIG_MAC80211_DEBUG_MENU is not set
728CONFIG_IEEE80211=m
729# CONFIG_IEEE80211_DEBUG is not set
730CONFIG_IEEE80211_CRYPT_WEP=m
731CONFIG_IEEE80211_CRYPT_CCMP=m
732CONFIG_IEEE80211_CRYPT_TKIP=m
733CONFIG_RFKILL=m
734CONFIG_RFKILL_INPUT=m
735CONFIG_RFKILL_LEDS=y
736# CONFIG_NET_9P is not set
737
738#
739# Device Drivers
740#
741
742#
743# Generic Driver Options
744#
745CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
746CONFIG_STANDALONE=y
747CONFIG_PREVENT_FIRMWARE_BUILD=y
748CONFIG_FW_LOADER=y
749CONFIG_FIRMWARE_IN_KERNEL=y
750CONFIG_EXTRA_FIRMWARE=""
751# CONFIG_DEBUG_DRIVER is not set
752CONFIG_DEBUG_DEVRES=y
753# CONFIG_SYS_HYPERVISOR is not set
754CONFIG_CONNECTOR=y
755CONFIG_PROC_EVENTS=y
756# CONFIG_MTD is not set
757# CONFIG_PARPORT is not set
758CONFIG_PNP=y
759# CONFIG_PNP_DEBUG is not set
760
761#
762# Protocols
763#
764CONFIG_PNPACPI=y
765CONFIG_BLK_DEV=y
766# CONFIG_BLK_DEV_FD is not set
767# CONFIG_BLK_CPQ_DA is not set
768# CONFIG_BLK_CPQ_CISS_DA is not set
769# CONFIG_BLK_DEV_DAC960 is not set
770# CONFIG_BLK_DEV_UMEM is not set
771# CONFIG_BLK_DEV_COW_COMMON is not set
772CONFIG_BLK_DEV_LOOP=y
773CONFIG_BLK_DEV_CRYPTOLOOP=m
774# CONFIG_BLK_DEV_NBD is not set
775# CONFIG_BLK_DEV_SX8 is not set
776# CONFIG_BLK_DEV_UB is not set
777CONFIG_BLK_DEV_RAM=y
778CONFIG_BLK_DEV_RAM_COUNT=16
779CONFIG_BLK_DEV_RAM_SIZE=262144
780# CONFIG_BLK_DEV_XIP is not set
781CONFIG_CDROM_PKTCDVD=m
782CONFIG_CDROM_PKTCDVD_BUFFERS=8
783# CONFIG_CDROM_PKTCDVD_WCACHE is not set
784# CONFIG_ATA_OVER_ETH is not set
785# CONFIG_BLK_DEV_HD is not set
786CONFIG_MISC_DEVICES=y
787# CONFIG_IBM_ASM is not set
788# CONFIG_PHANTOM is not set
789CONFIG_EEPROM_93CX6=m
790# CONFIG_SGI_IOC4 is not set
791CONFIG_TIFM_CORE=m
792CONFIG_TIFM_7XX1=m
793# CONFIG_ACER_WMI is not set
794# CONFIG_FUJITSU_LAPTOP is not set
795# CONFIG_TC1100_WMI is not set
796# CONFIG_HP_WMI is not set
797# CONFIG_MSI_LAPTOP is not set
798# CONFIG_COMPAL_LAPTOP is not set
799# CONFIG_SONY_LAPTOP is not set
800# CONFIG_THINKPAD_ACPI is not set
801# CONFIG_INTEL_MENLOW is not set
802CONFIG_EEEPC_LAPTOP=y
803# CONFIG_ENCLOSURE_SERVICES is not set
804# CONFIG_HP_ILO is not set
805CONFIG_HAVE_IDE=y
806# CONFIG_IDE is not set
807
808#
809# SCSI device support
810#
811CONFIG_RAID_ATTRS=m
812CONFIG_SCSI=y
813CONFIG_SCSI_DMA=y
814# CONFIG_SCSI_TGT is not set
815# CONFIG_SCSI_NETLINK is not set
816CONFIG_SCSI_PROC_FS=y
817
818#
819# SCSI support type (disk, tape, CD-ROM)
820#
821CONFIG_BLK_DEV_SD=y
822CONFIG_CHR_DEV_ST=m
823# CONFIG_CHR_DEV_OSST is not set
824CONFIG_BLK_DEV_SR=y
825CONFIG_BLK_DEV_SR_VENDOR=y
826# CONFIG_CHR_DEV_SG is not set
827CONFIG_CHR_DEV_SCH=m
828
829#
830# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
831#
832CONFIG_SCSI_MULTI_LUN=y
833CONFIG_SCSI_CONSTANTS=y
834CONFIG_SCSI_LOGGING=y
835CONFIG_SCSI_SCAN_ASYNC=y
836CONFIG_SCSI_WAIT_SCAN=m
837
838#
839# SCSI Transports
840#
841# CONFIG_SCSI_SPI_ATTRS is not set
842# CONFIG_SCSI_FC_ATTRS is not set
843# CONFIG_SCSI_ISCSI_ATTRS is not set
844# CONFIG_SCSI_SAS_ATTRS is not set
845# CONFIG_SCSI_SAS_LIBSAS is not set
846# CONFIG_SCSI_SRP_ATTRS is not set
847CONFIG_SCSI_LOWLEVEL=y
848# CONFIG_ISCSI_TCP is not set
849# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
850# CONFIG_SCSI_3W_9XXX is not set
851# CONFIG_SCSI_ACARD is not set
852# CONFIG_SCSI_AACRAID is not set
853# CONFIG_SCSI_AIC7XXX is not set
854# CONFIG_SCSI_AIC7XXX_OLD is not set
855# CONFIG_SCSI_AIC79XX is not set
856# CONFIG_SCSI_AIC94XX is not set
857# CONFIG_SCSI_DPT_I2O is not set
858# CONFIG_SCSI_ADVANSYS is not set
859# CONFIG_SCSI_ARCMSR is not set
860# CONFIG_MEGARAID_NEWGEN is not set
861# CONFIG_MEGARAID_LEGACY is not set
862# CONFIG_MEGARAID_SAS is not set
863# CONFIG_SCSI_HPTIOP is not set
864# CONFIG_SCSI_BUSLOGIC is not set
865# CONFIG_SCSI_DMX3191D is not set
866# CONFIG_SCSI_EATA is not set
867# CONFIG_SCSI_FUTURE_DOMAIN is not set
868# CONFIG_SCSI_GDTH is not set
869# CONFIG_SCSI_IPS is not set
870# CONFIG_SCSI_INITIO is not set
871# CONFIG_SCSI_INIA100 is not set
872# CONFIG_SCSI_MVSAS is not set
873# CONFIG_SCSI_STEX is not set
874# CONFIG_SCSI_SYM53C8XX_2 is not set
875# CONFIG_SCSI_IPR is not set
876# CONFIG_SCSI_QLOGIC_1280 is not set
877# CONFIG_SCSI_QLA_FC is not set
878# CONFIG_SCSI_QLA_ISCSI is not set
879# CONFIG_SCSI_LPFC is not set
880# CONFIG_SCSI_DC395x is not set
881# CONFIG_SCSI_DC390T is not set
882# CONFIG_SCSI_NSP32 is not set
883# CONFIG_SCSI_DEBUG is not set
884# CONFIG_SCSI_SRP is not set
885# CONFIG_SCSI_DH is not set
886CONFIG_ATA=y
887# CONFIG_ATA_NONSTANDARD is not set
888CONFIG_ATA_ACPI=y
889# CONFIG_SATA_PMP is not set
890CONFIG_SATA_AHCI=y
891# CONFIG_SATA_SIL24 is not set
892CONFIG_ATA_SFF=y
893# CONFIG_SATA_SVW is not set
894CONFIG_ATA_PIIX=y
895# CONFIG_SATA_MV is not set
896# CONFIG_SATA_NV is not set
897# CONFIG_PDC_ADMA is not set
898# CONFIG_SATA_QSTOR is not set
899# CONFIG_SATA_PROMISE is not set
900# CONFIG_SATA_SX4 is not set
901# CONFIG_SATA_SIL is not set
902# CONFIG_SATA_SIS is not set
903# CONFIG_SATA_ULI is not set
904# CONFIG_SATA_VIA is not set
905# CONFIG_SATA_VITESSE is not set
906# CONFIG_SATA_INIC162X is not set
907# CONFIG_PATA_ACPI is not set
908# CONFIG_PATA_ALI is not set
909# CONFIG_PATA_AMD is not set
910# CONFIG_PATA_ARTOP is not set
911# CONFIG_PATA_ATIIXP is not set
912# CONFIG_PATA_CMD640_PCI is not set
913# CONFIG_PATA_CMD64X is not set
914# CONFIG_PATA_CS5520 is not set
915# CONFIG_PATA_CS5530 is not set
916# CONFIG_PATA_CS5535 is not set
917# CONFIG_PATA_CS5536 is not set
918# CONFIG_PATA_CYPRESS is not set
919# CONFIG_PATA_EFAR is not set
920# CONFIG_ATA_GENERIC is not set
921# CONFIG_PATA_HPT366 is not set
922# CONFIG_PATA_HPT37X is not set
923# CONFIG_PATA_HPT3X2N is not set
924# CONFIG_PATA_HPT3X3 is not set
925# CONFIG_PATA_IT821X is not set
926# CONFIG_PATA_IT8213 is not set
927# CONFIG_PATA_JMICRON is not set
928# CONFIG_PATA_TRIFLEX is not set
929# CONFIG_PATA_MARVELL is not set
930# CONFIG_PATA_MPIIX is not set
931# CONFIG_PATA_OLDPIIX is not set
932# CONFIG_PATA_NETCELL is not set
933# CONFIG_PATA_NINJA32 is not set
934# CONFIG_PATA_NS87410 is not set
935# CONFIG_PATA_NS87415 is not set
936# CONFIG_PATA_OPTI is not set
937# CONFIG_PATA_OPTIDMA is not set
938# CONFIG_PATA_PDC_OLD is not set
939# CONFIG_PATA_RADISYS is not set
940# CONFIG_PATA_RZ1000 is not set
941# CONFIG_PATA_SC1200 is not set
942# CONFIG_PATA_SERVERWORKS is not set
943# CONFIG_PATA_PDC2027X is not set
944# CONFIG_PATA_SIL680 is not set
945# CONFIG_PATA_SIS is not set
946# CONFIG_PATA_VIA is not set
947# CONFIG_PATA_WINBOND is not set
948CONFIG_PATA_SCH=y
949# CONFIG_MD is not set
950# CONFIG_FUSION is not set
951
952#
953# IEEE 1394 (FireWire) support
954#
955
956#
957# Enable only one of the two stacks, unless you know what you are doing
958#
959# CONFIG_FIREWIRE is not set
960# CONFIG_IEEE1394 is not set
961# CONFIG_I2O is not set
962# CONFIG_MACINTOSH_DRIVERS is not set
963CONFIG_NETDEVICES=y
964# CONFIG_DUMMY is not set
965# CONFIG_BONDING is not set
966CONFIG_MACVLAN=m
967# CONFIG_EQUALIZER is not set
968# CONFIG_TUN is not set
969# CONFIG_VETH is not set
970# CONFIG_NET_SB1000 is not set
971# CONFIG_ARCNET is not set
972CONFIG_PHYLIB=m
973
974#
975# MII PHY device drivers
976#
977CONFIG_MARVELL_PHY=m
978CONFIG_DAVICOM_PHY=m
979CONFIG_QSEMI_PHY=m
980CONFIG_LXT_PHY=m
981CONFIG_CICADA_PHY=m
982CONFIG_VITESSE_PHY=m
983CONFIG_SMSC_PHY=m
984CONFIG_BROADCOM_PHY=m
985CONFIG_ICPLUS_PHY=m
986CONFIG_REALTEK_PHY=m
987CONFIG_MDIO_BITBANG=m
988CONFIG_NET_ETHERNET=y
989CONFIG_MII=m
990CONFIG_HAPPYMEAL=m
991CONFIG_SUNGEM=m
992CONFIG_CASSINI=m
993CONFIG_NET_VENDOR_3COM=y
994# CONFIG_VORTEX is not set
995# CONFIG_TYPHOON is not set
996# CONFIG_NET_TULIP is not set
997# CONFIG_HP100 is not set
998# CONFIG_IBM_NEW_EMAC_ZMII is not set
999# CONFIG_IBM_NEW_EMAC_RGMII is not set
1000# CONFIG_IBM_NEW_EMAC_TAH is not set
1001# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
1002# CONFIG_NET_PCI is not set
1003# CONFIG_B44 is not set
1004CONFIG_NETDEV_1000=y
1005# CONFIG_ACENIC is not set
1006# CONFIG_DL2K is not set
1007# CONFIG_E1000 is not set
1008# CONFIG_E1000E is not set
1009# CONFIG_IP1000 is not set
1010# CONFIG_IGB is not set
1011# CONFIG_NS83820 is not set
1012# CONFIG_HAMACHI is not set
1013# CONFIG_YELLOWFIN is not set
1014# CONFIG_R8169 is not set
1015# CONFIG_SIS190 is not set
1016# CONFIG_SKGE is not set
1017# CONFIG_SKY2 is not set
1018# CONFIG_VIA_VELOCITY is not set
1019# CONFIG_TIGON3 is not set
1020# CONFIG_BNX2 is not set
1021# CONFIG_QLA3XXX is not set
1022CONFIG_ATL1=m
1023CONFIG_ATL1E=m
1024# CONFIG_NETDEV_10000 is not set
1025# CONFIG_TR is not set
1026
1027#
1028# Wireless LAN
1029#
1030CONFIG_WLAN_PRE80211=y
1031# CONFIG_STRIP is not set
1032CONFIG_WLAN_80211=y
1033# CONFIG_IPW2100 is not set
1034# CONFIG_IPW2200 is not set
1035# CONFIG_LIBERTAS is not set
1036# CONFIG_AIRO is not set
1037# CONFIG_HERMES is not set
1038# CONFIG_ATMEL is not set
1039# CONFIG_PRISM54 is not set
1040CONFIG_USB_ZD1201=m
1041CONFIG_USB_NET_RNDIS_WLAN=m
1042CONFIG_RTL8180=m
1043CONFIG_RTL8187=m
1044# CONFIG_ADM8211 is not set
1045# CONFIG_MAC80211_HWSIM is not set
1046# CONFIG_P54_COMMON is not set
1047CONFIG_ATH5K=m
1048# CONFIG_ATH5K_DEBUG is not set
1049CONFIG_IWLWIFI=m
1050CONFIG_IWLCORE=m
1051# CONFIG_IWLWIFI_LEDS is not set
1052CONFIG_IWLWIFI_RFKILL=y
1053CONFIG_IWL4965=m
1054# CONFIG_IWL4965_LEDS is not set
1055# CONFIG_IWL4965_SPECTRUM_MEASUREMENT is not set
1056# CONFIG_IWLWIFI_DEBUG is not set
1057CONFIG_IWL5000=y
1058CONFIG_IWL3945=m
1059CONFIG_IWL3945_RFKILL=y
1060# CONFIG_IWL3945_SPECTRUM_MEASUREMENT is not set
1061# CONFIG_IWL3945_LEDS is not set
1062# CONFIG_IWL3945_DEBUG is not set
1063# CONFIG_HOSTAP is not set
1064# CONFIG_B43 is not set
1065# CONFIG_B43LEGACY is not set
1066# CONFIG_ZD1211RW is not set
1067CONFIG_RT2X00=m
1068CONFIG_RT2X00_LIB=m
1069CONFIG_RT2X00_LIB_PCI=m
1070CONFIG_RT2X00_LIB_USB=m
1071CONFIG_RT2X00_LIB_FIRMWARE=y
1072CONFIG_RT2X00_LIB_RFKILL=y
1073CONFIG_RT2X00_LIB_LEDS=y
1074CONFIG_RT2400PCI=m
1075CONFIG_RT2400PCI_RFKILL=y
1076CONFIG_RT2400PCI_LEDS=y
1077CONFIG_RT2500PCI=m
1078CONFIG_RT2500PCI_RFKILL=y
1079CONFIG_RT2500PCI_LEDS=y
1080CONFIG_RT61PCI=m
1081CONFIG_RT61PCI_RFKILL=y
1082CONFIG_RT61PCI_LEDS=y
1083CONFIG_RT2500USB=m
1084CONFIG_RT2500USB_LEDS=y
1085CONFIG_RT73USB=m
1086CONFIG_RT73USB_LEDS=y
1087CONFIG_RT2X00_LIB_DEBUGFS=y
1088# CONFIG_RT2X00_DEBUG is not set
1089
1090#
1091# USB Network Adapters
1092#
1093CONFIG_USB_CATC=m
1094CONFIG_USB_KAWETH=m
1095CONFIG_USB_PEGASUS=m
1096CONFIG_USB_RTL8150=m
1097CONFIG_USB_USBNET=m
1098CONFIG_USB_NET_AX8817X=m
1099# CONFIG_USB_HSO is not set
1100CONFIG_USB_NET_CDCETHER=m
1101CONFIG_USB_NET_DM9601=m
1102CONFIG_USB_NET_GL620A=m
1103CONFIG_USB_NET_NET1080=m
1104CONFIG_USB_NET_PLUSB=m
1105CONFIG_USB_NET_MCS7830=m
1106CONFIG_USB_NET_RNDIS_HOST=m
1107CONFIG_USB_NET_CDC_SUBSET=m
1108CONFIG_USB_ALI_M5632=y
1109CONFIG_USB_AN2720=y
1110CONFIG_USB_BELKIN=y
1111CONFIG_USB_ARMLINUX=y
1112CONFIG_USB_EPSON2888=y
1113CONFIG_USB_KC2190=y
1114CONFIG_USB_NET_ZAURUS=m
1115# CONFIG_WAN is not set
1116# CONFIG_FDDI is not set
1117# CONFIG_HIPPI is not set
1118CONFIG_PPP=m
1119CONFIG_PPP_MULTILINK=y
1120CONFIG_PPP_FILTER=y
1121CONFIG_PPP_ASYNC=m
1122CONFIG_PPP_SYNC_TTY=m
1123CONFIG_PPP_DEFLATE=m
1124# CONFIG_PPP_BSDCOMP is not set
1125CONFIG_PPP_MPPE=m
1126CONFIG_PPPOE=m
1127CONFIG_PPPOL2TP=m
1128# CONFIG_SLIP is not set
1129CONFIG_SLHC=m
1130CONFIG_NET_FC=y
1131CONFIG_NETCONSOLE=m
1132CONFIG_NETCONSOLE_DYNAMIC=y
1133CONFIG_NETPOLL=y
1134CONFIG_NETPOLL_TRAP=y
1135CONFIG_NET_POLL_CONTROLLER=y
1136# CONFIG_ISDN is not set
1137# CONFIG_PHONE is not set
1138
1139#
1140# Input device support
1141#
1142CONFIG_INPUT=y
1143CONFIG_INPUT_FF_MEMLESS=y
1144CONFIG_INPUT_POLLDEV=m
1145
1146#
1147# Userland interfaces
1148#
1149CONFIG_INPUT_MOUSEDEV=y
1150# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
1151CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
1152CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
1153CONFIG_INPUT_JOYDEV=m
1154CONFIG_INPUT_EVDEV=y
1155# CONFIG_INPUT_EVBUG is not set
1156
1157#
1158# Input Device Drivers
1159#
1160CONFIG_INPUT_KEYBOARD=y
1161CONFIG_KEYBOARD_ATKBD=y
1162# CONFIG_KEYBOARD_SUNKBD is not set
1163# CONFIG_KEYBOARD_LKKBD is not set
1164# CONFIG_KEYBOARD_XTKBD is not set
1165# CONFIG_KEYBOARD_NEWTON is not set
1166# CONFIG_KEYBOARD_STOWAWAY is not set
1167CONFIG_INPUT_MOUSE=y
1168CONFIG_MOUSE_PS2=y
1169CONFIG_MOUSE_PS2_ALPS=y
1170CONFIG_MOUSE_PS2_LOGIPS2PP=y
1171CONFIG_MOUSE_PS2_SYNAPTICS=y
1172CONFIG_MOUSE_PS2_LIFEBOOK=y
1173CONFIG_MOUSE_PS2_TRACKPOINT=y
1174# CONFIG_MOUSE_PS2_TOUCHKIT is not set
1175CONFIG_MOUSE_SERIAL=m
1176# CONFIG_MOUSE_APPLETOUCH is not set
1177CONFIG_MOUSE_VSXXXAA=m
1178CONFIG_INPUT_JOYSTICK=y
1179# CONFIG_JOYSTICK_ANALOG is not set
1180# CONFIG_JOYSTICK_A3D is not set
1181# CONFIG_JOYSTICK_ADI is not set
1182# CONFIG_JOYSTICK_COBRA is not set
1183# CONFIG_JOYSTICK_GF2K is not set
1184# CONFIG_JOYSTICK_GRIP is not set
1185# CONFIG_JOYSTICK_GRIP_MP is not set
1186# CONFIG_JOYSTICK_GUILLEMOT is not set
1187# CONFIG_JOYSTICK_INTERACT is not set
1188# CONFIG_JOYSTICK_SIDEWINDER is not set
1189# CONFIG_JOYSTICK_TMDC is not set
1190# CONFIG_JOYSTICK_IFORCE is not set
1191# CONFIG_JOYSTICK_WARRIOR is not set
1192# CONFIG_JOYSTICK_MAGELLAN is not set
1193# CONFIG_JOYSTICK_SPACEORB is not set
1194# CONFIG_JOYSTICK_SPACEBALL is not set
1195# CONFIG_JOYSTICK_STINGER is not set
1196# CONFIG_JOYSTICK_TWIDJOY is not set
1197# CONFIG_JOYSTICK_ZHENHUA is not set
1198# CONFIG_JOYSTICK_JOYDUMP is not set
1199# CONFIG_JOYSTICK_XPAD is not set
1200# CONFIG_INPUT_TABLET is not set
1201CONFIG_INPUT_TOUCHSCREEN=y
1202CONFIG_TOUCHSCREEN_FUJITSU=m
1203CONFIG_TOUCHSCREEN_GUNZE=m
1204CONFIG_TOUCHSCREEN_ELO=m
1205CONFIG_TOUCHSCREEN_MTOUCH=m
1206CONFIG_TOUCHSCREEN_INEXIO=m
1207CONFIG_TOUCHSCREEN_MK712=m
1208CONFIG_TOUCHSCREEN_PENMOUNT=m
1209CONFIG_TOUCHSCREEN_TOUCHRIGHT=m
1210CONFIG_TOUCHSCREEN_TOUCHWIN=m
1211CONFIG_TOUCHSCREEN_UCB1400=m
1212# CONFIG_TOUCHSCREEN_WM97XX is not set
1213CONFIG_TOUCHSCREEN_USB_COMPOSITE=m
1214CONFIG_TOUCHSCREEN_USB_EGALAX=y
1215CONFIG_TOUCHSCREEN_USB_PANJIT=y
1216CONFIG_TOUCHSCREEN_USB_3M=y
1217CONFIG_TOUCHSCREEN_USB_ITM=y
1218CONFIG_TOUCHSCREEN_USB_ETURBO=y
1219CONFIG_TOUCHSCREEN_USB_GUNZE=y
1220CONFIG_TOUCHSCREEN_USB_DMC_TSC10=y
1221CONFIG_TOUCHSCREEN_USB_IRTOUCH=y
1222CONFIG_TOUCHSCREEN_USB_IDEALTEK=y
1223CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH=y
1224CONFIG_TOUCHSCREEN_USB_GOTOP=y
1225CONFIG_TOUCHSCREEN_TOUCHIT213=m
1226CONFIG_INPUT_MISC=y
1227# CONFIG_INPUT_PCSPKR is not set
1228# CONFIG_INPUT_APANEL is not set
1229# CONFIG_INPUT_WISTRON_BTNS is not set
1230CONFIG_INPUT_ATLAS_BTNS=m
1231CONFIG_INPUT_ATI_REMOTE=m
1232CONFIG_INPUT_ATI_REMOTE2=m
1233CONFIG_INPUT_KEYSPAN_REMOTE=m
1234CONFIG_INPUT_POWERMATE=m
1235CONFIG_INPUT_YEALINK=m
1236CONFIG_INPUT_UINPUT=m
1237
1238#
1239# Hardware I/O ports
1240#
1241CONFIG_SERIO=y
1242CONFIG_SERIO_I8042=y
1243CONFIG_SERIO_SERPORT=y
1244# CONFIG_SERIO_CT82C710 is not set
1245# CONFIG_SERIO_PCIPS2 is not set
1246CONFIG_SERIO_LIBPS2=y
1247CONFIG_SERIO_RAW=m
1248# CONFIG_GAMEPORT is not set
1249
1250#
1251# Character devices
1252#
1253CONFIG_VT=y
1254CONFIG_CONSOLE_TRANSLATIONS=y
1255CONFIG_VT_CONSOLE=y
1256CONFIG_HW_CONSOLE=y
1257CONFIG_VT_HW_CONSOLE_BINDING=y
1258# CONFIG_DEVKMEM is not set
1259# CONFIG_SERIAL_NONSTANDARD is not set
1260# CONFIG_NOZOMI is not set
1261
1262#
1263# Serial drivers
1264#
1265# CONFIG_SERIAL_8250 is not set
1266CONFIG_FIX_EARLYCON_MEM=y
1267
1268#
1269# Non-8250 serial port support
1270#
1271# CONFIG_SERIAL_JSM is not set
1272CONFIG_UNIX98_PTYS=y
1273# CONFIG_LEGACY_PTYS is not set
1274# CONFIG_IPMI_HANDLER is not set
1275# CONFIG_HW_RANDOM is not set
1276# CONFIG_NVRAM is not set
1277# CONFIG_R3964 is not set
1278# CONFIG_APPLICOM is not set
1279# CONFIG_SONYPI is not set
1280# CONFIG_MWAVE is not set
1281# CONFIG_PC8736x_GPIO is not set
1282# CONFIG_NSC_GPIO is not set
1283# CONFIG_CS5535_GPIO is not set
1284# CONFIG_RAW_DRIVER is not set
1285CONFIG_HPET=y
1286# CONFIG_HPET_MMAP is not set
1287# CONFIG_HANGCHECK_TIMER is not set
1288# CONFIG_TCG_TPM is not set
1289# CONFIG_TELCLOCK is not set
1290CONFIG_DEVPORT=y
1291CONFIG_I2C=y
1292CONFIG_I2C_BOARDINFO=y
1293# CONFIG_I2C_CHARDEV is not set
1294CONFIG_I2C_ALGOBIT=y
1295
1296#
1297# I2C Hardware Bus support
1298#
1299
1300#
1301# PC SMBus host controller drivers
1302#
1303# CONFIG_I2C_ALI1535 is not set
1304# CONFIG_I2C_ALI1563 is not set
1305# CONFIG_I2C_ALI15X3 is not set
1306# CONFIG_I2C_AMD756 is not set
1307# CONFIG_I2C_AMD8111 is not set
1308# CONFIG_I2C_I801 is not set
1309# CONFIG_I2C_ISCH is not set
1310# CONFIG_I2C_PIIX4 is not set
1311# CONFIG_I2C_NFORCE2 is not set
1312# CONFIG_I2C_SIS5595 is not set
1313# CONFIG_I2C_SIS630 is not set
1314# CONFIG_I2C_SIS96X is not set
1315# CONFIG_I2C_VIA is not set
1316# CONFIG_I2C_VIAPRO is not set
1317
1318#
1319# I2C system bus drivers (mostly embedded / system-on-chip)
1320#
1321# CONFIG_I2C_OCORES is not set
1322# CONFIG_I2C_SIMTEC is not set
1323
1324#
1325# External I2C/SMBus adapter drivers
1326#
1327# CONFIG_I2C_PARPORT_LIGHT is not set
1328# CONFIG_I2C_TAOS_EVM is not set
1329# CONFIG_I2C_TINY_USB is not set
1330
1331#
1332# Graphics adapter I2C/DDC channel drivers
1333#
1334# CONFIG_I2C_VOODOO3 is not set
1335
1336#
1337# Other I2C/SMBus bus drivers
1338#
1339# CONFIG_I2C_PCA_PLATFORM is not set
1340# CONFIG_I2C_STUB is not set
1341# CONFIG_SCx200_ACB is not set
1342
1343#
1344# Miscellaneous I2C Chip support
1345#
1346# CONFIG_DS1682 is not set
1347# CONFIG_AT24 is not set
1348# CONFIG_SENSORS_EEPROM is not set
1349# CONFIG_SENSORS_PCF8574 is not set
1350# CONFIG_PCF8575 is not set
1351# CONFIG_SENSORS_PCA9539 is not set
1352# CONFIG_SENSORS_PCF8591 is not set
1353# CONFIG_SENSORS_MAX6875 is not set
1354# CONFIG_SENSORS_TSL2550 is not set
1355# CONFIG_I2C_DEBUG_CORE is not set
1356# CONFIG_I2C_DEBUG_ALGO is not set
1357# CONFIG_I2C_DEBUG_BUS is not set
1358# CONFIG_I2C_DEBUG_CHIP is not set
1359# CONFIG_SPI is not set
1360CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
1361# CONFIG_GPIOLIB is not set
1362# CONFIG_W1 is not set
1363CONFIG_POWER_SUPPLY=y
1364# CONFIG_POWER_SUPPLY_DEBUG is not set
1365# CONFIG_PDA_POWER is not set
1366# CONFIG_BATTERY_DS2760 is not set
1367CONFIG_HWMON=y
1368# CONFIG_HWMON_VID is not set
1369# CONFIG_SENSORS_ABITUGURU is not set
1370# CONFIG_SENSORS_ABITUGURU3 is not set
1371# CONFIG_SENSORS_AD7418 is not set
1372# CONFIG_SENSORS_ADM1021 is not set
1373# CONFIG_SENSORS_ADM1025 is not set
1374# CONFIG_SENSORS_ADM1026 is not set
1375# CONFIG_SENSORS_ADM1029 is not set
1376# CONFIG_SENSORS_ADM1031 is not set
1377# CONFIG_SENSORS_ADM9240 is not set
1378# CONFIG_SENSORS_ADT7470 is not set
1379# CONFIG_SENSORS_ADT7473 is not set
1380# CONFIG_SENSORS_K8TEMP is not set
1381# CONFIG_SENSORS_ASB100 is not set
1382# CONFIG_SENSORS_ATXP1 is not set
1383# CONFIG_SENSORS_DS1621 is not set
1384# CONFIG_SENSORS_I5K_AMB is not set
1385# CONFIG_SENSORS_F71805F is not set
1386# CONFIG_SENSORS_F71882FG is not set
1387# CONFIG_SENSORS_F75375S is not set
1388# CONFIG_SENSORS_FSCHER is not set
1389# CONFIG_SENSORS_FSCPOS is not set
1390# CONFIG_SENSORS_FSCHMD is not set
1391# CONFIG_SENSORS_GL518SM is not set
1392# CONFIG_SENSORS_GL520SM is not set
1393CONFIG_SENSORS_CORETEMP=y
1394# CONFIG_SENSORS_IT87 is not set
1395# CONFIG_SENSORS_LM63 is not set
1396# CONFIG_SENSORS_LM75 is not set
1397# CONFIG_SENSORS_LM77 is not set
1398# CONFIG_SENSORS_LM78 is not set
1399# CONFIG_SENSORS_LM80 is not set
1400# CONFIG_SENSORS_LM83 is not set
1401# CONFIG_SENSORS_LM85 is not set
1402# CONFIG_SENSORS_LM87 is not set
1403# CONFIG_SENSORS_LM90 is not set
1404# CONFIG_SENSORS_LM92 is not set
1405# CONFIG_SENSORS_LM93 is not set
1406# CONFIG_SENSORS_MAX1619 is not set
1407# CONFIG_SENSORS_MAX6650 is not set
1408# CONFIG_SENSORS_PC87360 is not set
1409# CONFIG_SENSORS_PC87427 is not set
1410# CONFIG_SENSORS_SIS5595 is not set
1411# CONFIG_SENSORS_DME1737 is not set
1412# CONFIG_SENSORS_SMSC47M1 is not set
1413# CONFIG_SENSORS_SMSC47M192 is not set
1414# CONFIG_SENSORS_SMSC47B397 is not set
1415# CONFIG_SENSORS_ADS7828 is not set
1416# CONFIG_SENSORS_THMC50 is not set
1417# CONFIG_SENSORS_VIA686A is not set
1418# CONFIG_SENSORS_VT1211 is not set
1419# CONFIG_SENSORS_VT8231 is not set
1420# CONFIG_SENSORS_W83781D is not set
1421# CONFIG_SENSORS_W83791D is not set
1422# CONFIG_SENSORS_W83792D is not set
1423# CONFIG_SENSORS_W83793 is not set
1424# CONFIG_SENSORS_W83L785TS is not set
1425# CONFIG_SENSORS_W83L786NG is not set
1426# CONFIG_SENSORS_W83627HF is not set
1427# CONFIG_SENSORS_W83627EHF is not set
1428# CONFIG_SENSORS_HDAPS is not set
1429# CONFIG_SENSORS_APPLESMC is not set
1430# CONFIG_HWMON_DEBUG_CHIP is not set
1431CONFIG_THERMAL=y
1432# CONFIG_THERMAL_HWMON is not set
1433# CONFIG_WATCHDOG is not set
1434
1435#
1436# Sonics Silicon Backplane
1437#
1438CONFIG_SSB_POSSIBLE=y
1439# CONFIG_SSB is not set
1440
1441#
1442# Multifunction device drivers
1443#
1444# CONFIG_MFD_CORE is not set
1445# CONFIG_MFD_SM501 is not set
1446# CONFIG_HTC_PASIC3 is not set
1447
1448#
1449# Multimedia devices
1450#
1451
1452#
1453# Multimedia core support
1454#
1455CONFIG_VIDEO_DEV=y
1456CONFIG_VIDEO_V4L2_COMMON=y
1457# CONFIG_VIDEO_ALLOW_V4L1 is not set
1458CONFIG_VIDEO_V4L1_COMPAT=y
1459CONFIG_DVB_CORE=y
1460CONFIG_VIDEO_MEDIA=y
1461
1462#
1463# Multimedia drivers
1464#
1465# CONFIG_MEDIA_ATTACH is not set
1466CONFIG_MEDIA_TUNER=y
1467# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set
1468CONFIG_MEDIA_TUNER_SIMPLE=y
1469CONFIG_MEDIA_TUNER_TDA8290=y
1470CONFIG_MEDIA_TUNER_TDA9887=y
1471CONFIG_MEDIA_TUNER_TEA5761=y
1472CONFIG_MEDIA_TUNER_TEA5767=y
1473CONFIG_MEDIA_TUNER_MT20XX=y
1474CONFIG_MEDIA_TUNER_XC2028=y
1475CONFIG_MEDIA_TUNER_XC5000=y
1476CONFIG_VIDEO_V4L2=y
1477CONFIG_VIDEO_CAPTURE_DRIVERS=y
1478# CONFIG_VIDEO_ADV_DEBUG is not set
1479CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
1480# CONFIG_VIDEO_VIVI is not set
1481# CONFIG_VIDEO_BT848 is not set
1482# CONFIG_VIDEO_SAA5246A is not set
1483# CONFIG_VIDEO_SAA5249 is not set
1484# CONFIG_VIDEO_SAA7134 is not set
1485# CONFIG_VIDEO_HEXIUM_ORION is not set
1486# CONFIG_VIDEO_HEXIUM_GEMINI is not set
1487# CONFIG_VIDEO_CX88 is not set
1488# CONFIG_VIDEO_CX23885 is not set
1489# CONFIG_VIDEO_AU0828 is not set
1490# CONFIG_VIDEO_CX18 is not set
1491# CONFIG_VIDEO_CAFE_CCIC is not set
1492CONFIG_V4L_USB_DRIVERS=y
1493CONFIG_USB_VIDEO_CLASS=y
1494CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y
1495# CONFIG_USB_GSPCA is not set
1496# CONFIG_VIDEO_PVRUSB2 is not set
1497# CONFIG_VIDEO_EM28XX is not set
1498# CONFIG_VIDEO_USBVISION is not set
1499# CONFIG_USB_ET61X251 is not set
1500# CONFIG_USB_SN9C102 is not set
1501# CONFIG_USB_ZC0301 is not set
1502# CONFIG_USB_ZR364XX is not set
1503# CONFIG_USB_STKWEBCAM is not set
1504# CONFIG_USB_S2255 is not set
1505# CONFIG_SOC_CAMERA is not set
1506# CONFIG_VIDEO_SH_MOBILE_CEU is not set
1507# CONFIG_RADIO_ADAPTERS is not set
1508# CONFIG_DVB_CAPTURE_DRIVERS is not set
1509# CONFIG_DAB is not set
1510
1511#
1512# Graphics support
1513#
1514CONFIG_AGP=y
1515# CONFIG_AGP_ALI is not set
1516# CONFIG_AGP_ATI is not set
1517# CONFIG_AGP_AMD is not set
1518CONFIG_AGP_AMD64=y
1519CONFIG_AGP_INTEL=y
1520# CONFIG_AGP_NVIDIA is not set
1521# CONFIG_AGP_SIS is not set
1522# CONFIG_AGP_SWORKS is not set
1523# CONFIG_AGP_VIA is not set
1524# CONFIG_AGP_EFFICEON is not set
1525CONFIG_DRM=y
1526# CONFIG_DRM_TDFX is not set
1527# CONFIG_DRM_R128 is not set
1528# CONFIG_DRM_RADEON is not set
1529CONFIG_DRM_I810=y
1530# CONFIG_DRM_I830 is not set
1531CONFIG_DRM_I915=y
1532# CONFIG_DRM_MGA is not set
1533# CONFIG_DRM_SIS is not set
1534# CONFIG_DRM_VIA is not set
1535# CONFIG_DRM_SAVAGE is not set
1536# CONFIG_VGASTATE is not set
1537CONFIG_VIDEO_OUTPUT_CONTROL=y
1538CONFIG_FB=y
1539CONFIG_FIRMWARE_EDID=y
1540CONFIG_FB_DDC=y
1541CONFIG_FB_CFB_FILLRECT=y
1542CONFIG_FB_CFB_COPYAREA=y
1543CONFIG_FB_CFB_IMAGEBLIT=y
1544# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
1545# CONFIG_FB_SYS_FILLRECT is not set
1546# CONFIG_FB_SYS_COPYAREA is not set
1547# CONFIG_FB_SYS_IMAGEBLIT is not set
1548# CONFIG_FB_FOREIGN_ENDIAN is not set
1549# CONFIG_FB_SYS_FOPS is not set
1550# CONFIG_FB_SVGALIB is not set
1551# CONFIG_FB_MACMODES is not set
1552# CONFIG_FB_BACKLIGHT is not set
1553CONFIG_FB_MODE_HELPERS=y
1554# CONFIG_FB_TILEBLITTING is not set
1555
1556#
1557# Frame buffer hardware drivers
1558#
1559# CONFIG_FB_CIRRUS is not set
1560# CONFIG_FB_PM2 is not set
1561# CONFIG_FB_CYBER2000 is not set
1562# CONFIG_FB_ARC is not set
1563# CONFIG_FB_ASILIANT is not set
1564# CONFIG_FB_IMSTT is not set
1565# CONFIG_FB_VGA16 is not set
1566# CONFIG_FB_UVESA is not set
1567# CONFIG_FB_VESA is not set
1568# CONFIG_FB_EFI is not set
1569# CONFIG_FB_N411 is not set
1570# CONFIG_FB_HGA is not set
1571# CONFIG_FB_S1D13XXX is not set
1572# CONFIG_FB_NVIDIA is not set
1573# CONFIG_FB_RIVA is not set
1574# CONFIG_FB_I810 is not set
1575# CONFIG_FB_LE80578 is not set
1576CONFIG_FB_INTEL=y
1577CONFIG_FB_INTEL_DEBUG=y
1578CONFIG_FB_INTEL_I2C=y
1579# CONFIG_FB_MATROX is not set
1580# CONFIG_FB_RADEON is not set
1581# CONFIG_FB_ATY128 is not set
1582# CONFIG_FB_ATY is not set
1583# CONFIG_FB_S3 is not set
1584# CONFIG_FB_SAVAGE is not set
1585# CONFIG_FB_SIS is not set
1586# CONFIG_FB_NEOMAGIC is not set
1587# CONFIG_FB_KYRO is not set
1588# CONFIG_FB_3DFX is not set
1589# CONFIG_FB_VOODOO1 is not set
1590# CONFIG_FB_VT8623 is not set
1591# CONFIG_FB_CYBLA is not set
1592# CONFIG_FB_TRIDENT is not set
1593# CONFIG_FB_ARK is not set
1594# CONFIG_FB_PM3 is not set
1595# CONFIG_FB_CARMINE is not set
1596# CONFIG_FB_GEODE is not set
1597# CONFIG_FB_VIRTUAL is not set
1598CONFIG_BACKLIGHT_LCD_SUPPORT=y
1599CONFIG_LCD_CLASS_DEVICE=y
1600# CONFIG_LCD_ILI9320 is not set
1601CONFIG_LCD_PLATFORM=y
1602CONFIG_BACKLIGHT_CLASS_DEVICE=y
1603# CONFIG_BACKLIGHT_CORGI is not set
1604# CONFIG_BACKLIGHT_PROGEAR is not set
1605CONFIG_BACKLIGHT_MBP_NVIDIA=y
1606
1607#
1608# Display device support
1609#
1610CONFIG_DISPLAY_SUPPORT=y
1611
1612#
1613# Display hardware drivers
1614#
1615
1616#
1617# Console display driver support
1618#
1619CONFIG_VGA_CONSOLE=y
1620CONFIG_VGACON_SOFT_SCROLLBACK=y
1621CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=64
1622CONFIG_VIDEO_SELECT=y
1623CONFIG_DUMMY_CONSOLE=y
1624CONFIG_FRAMEBUFFER_CONSOLE=y
1625# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
1626# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
1627# CONFIG_FONTS is not set
1628CONFIG_FONT_8x8=y
1629CONFIG_FONT_8x16=y
1630# CONFIG_LOGO is not set
1631CONFIG_SOUND=y
1632CONFIG_SND=y
1633CONFIG_SND_TIMER=y
1634CONFIG_SND_PCM=y
1635CONFIG_SND_HWDEP=y
1636CONFIG_SND_RAWMIDI=m
1637CONFIG_SND_SEQUENCER=y
1638CONFIG_SND_SEQ_DUMMY=y
1639# CONFIG_SND_MIXER_OSS is not set
1640# CONFIG_SND_PCM_OSS is not set
1641# CONFIG_SND_SEQUENCER_OSS is not set
1642CONFIG_SND_DYNAMIC_MINORS=y
1643# CONFIG_SND_SUPPORT_OLD_API is not set
1644CONFIG_SND_VERBOSE_PROCFS=y
1645CONFIG_SND_VERBOSE_PRINTK=y
1646CONFIG_SND_DEBUG=y
1647# CONFIG_SND_DEBUG_VERBOSE is not set
1648CONFIG_SND_PCM_XRUN_DEBUG=y
1649CONFIG_SND_VMASTER=y
1650CONFIG_SND_AC97_CODEC=y
1651CONFIG_SND_DRIVERS=y
1652# CONFIG_SND_PCSP is not set
1653# CONFIG_SND_DUMMY is not set
1654# CONFIG_SND_VIRMIDI is not set
1655# CONFIG_SND_MTPAV is not set
1656# CONFIG_SND_SERIAL_U16550 is not set
1657# CONFIG_SND_MPU401 is not set
1658CONFIG_SND_AC97_POWER_SAVE=y
1659CONFIG_SND_AC97_POWER_SAVE_DEFAULT=5
1660CONFIG_SND_PCI=y
1661# CONFIG_SND_AD1889 is not set
1662# CONFIG_SND_ALS300 is not set
1663# CONFIG_SND_ALS4000 is not set
1664# CONFIG_SND_ALI5451 is not set
1665# CONFIG_SND_ATIIXP is not set
1666# CONFIG_SND_ATIIXP_MODEM is not set
1667# CONFIG_SND_AU8810 is not set
1668# CONFIG_SND_AU8820 is not set
1669# CONFIG_SND_AU8830 is not set
1670# CONFIG_SND_AW2 is not set
1671# CONFIG_SND_AZT3328 is not set
1672# CONFIG_SND_BT87X is not set
1673# CONFIG_SND_CA0106 is not set
1674# CONFIG_SND_CMIPCI is not set
1675# CONFIG_SND_OXYGEN is not set
1676# CONFIG_SND_CS4281 is not set
1677# CONFIG_SND_CS46XX is not set
1678# CONFIG_SND_CS5530 is not set
1679# CONFIG_SND_CS5535AUDIO is not set
1680# CONFIG_SND_DARLA20 is not set
1681# CONFIG_SND_GINA20 is not set
1682# CONFIG_SND_LAYLA20 is not set
1683# CONFIG_SND_DARLA24 is not set
1684# CONFIG_SND_GINA24 is not set
1685# CONFIG_SND_LAYLA24 is not set
1686# CONFIG_SND_MONA is not set
1687# CONFIG_SND_MIA is not set
1688# CONFIG_SND_ECHO3G is not set
1689# CONFIG_SND_INDIGO is not set
1690# CONFIG_SND_INDIGOIO is not set
1691# CONFIG_SND_INDIGODJ is not set
1692# CONFIG_SND_EMU10K1 is not set
1693# CONFIG_SND_EMU10K1X is not set
1694# CONFIG_SND_ENS1370 is not set
1695# CONFIG_SND_ENS1371 is not set
1696# CONFIG_SND_ES1938 is not set
1697# CONFIG_SND_ES1968 is not set
1698# CONFIG_SND_FM801 is not set
1699CONFIG_SND_HDA_INTEL=y
1700CONFIG_SND_HDA_HWDEP=y
1701CONFIG_SND_HDA_CODEC_REALTEK=y
1702CONFIG_SND_HDA_CODEC_ANALOG=y
1703CONFIG_SND_HDA_CODEC_SIGMATEL=y
1704CONFIG_SND_HDA_CODEC_VIA=y
1705CONFIG_SND_HDA_CODEC_ATIHDMI=y
1706CONFIG_SND_HDA_CODEC_CONEXANT=y
1707CONFIG_SND_HDA_CODEC_CMEDIA=y
1708CONFIG_SND_HDA_CODEC_SI3054=y
1709CONFIG_SND_HDA_GENERIC=y
1710CONFIG_SND_HDA_POWER_SAVE=y
1711CONFIG_SND_HDA_POWER_SAVE_DEFAULT=0
1712# CONFIG_SND_HDSP is not set
1713# CONFIG_SND_HDSPM is not set
1714# CONFIG_SND_HIFIER is not set
1715# CONFIG_SND_ICE1712 is not set
1716# CONFIG_SND_ICE1724 is not set
1717CONFIG_SND_INTEL8X0=y
1718# CONFIG_SND_INTEL8X0M is not set
1719# CONFIG_SND_KORG1212 is not set
1720# CONFIG_SND_MAESTRO3 is not set
1721# CONFIG_SND_MIXART is not set
1722# CONFIG_SND_NM256 is not set
1723# CONFIG_SND_PCXHR is not set
1724# CONFIG_SND_RIPTIDE is not set
1725# CONFIG_SND_RME32 is not set
1726# CONFIG_SND_RME96 is not set
1727# CONFIG_SND_RME9652 is not set
1728# CONFIG_SND_SIS7019 is not set
1729# CONFIG_SND_SONICVIBES is not set
1730# CONFIG_SND_TRIDENT is not set
1731# CONFIG_SND_VIA82XX is not set
1732# CONFIG_SND_VIA82XX_MODEM is not set
1733# CONFIG_SND_VIRTUOSO is not set
1734# CONFIG_SND_VX222 is not set
1735# CONFIG_SND_YMFPCI is not set
1736CONFIG_SND_USB=y
1737CONFIG_SND_USB_AUDIO=m
1738CONFIG_SND_USB_USX2Y=m
1739CONFIG_SND_USB_CAIAQ=m
1740CONFIG_SND_USB_CAIAQ_INPUT=y
1741# CONFIG_SND_SOC is not set
1742# CONFIG_SOUND_PRIME is not set
1743CONFIG_AC97_BUS=y
1744CONFIG_HID_SUPPORT=y
1745CONFIG_HID=y
1746CONFIG_HID_DEBUG=y
1747CONFIG_HIDRAW=y
1748
1749#
1750# USB Input Devices
1751#
1752CONFIG_USB_HID=y
1753CONFIG_USB_HIDINPUT_POWERBOOK=y
1754CONFIG_HID_FF=y
1755CONFIG_HID_PID=y
1756CONFIG_LOGITECH_FF=y
1757# CONFIG_LOGIRUMBLEPAD2_FF is not set
1758CONFIG_PANTHERLORD_FF=y
1759CONFIG_THRUSTMASTER_FF=y
1760CONFIG_ZEROPLUS_FF=y
1761CONFIG_USB_HIDDEV=y
1762CONFIG_USB_SUPPORT=y
1763CONFIG_USB_ARCH_HAS_HCD=y
1764CONFIG_USB_ARCH_HAS_OHCI=y
1765CONFIG_USB_ARCH_HAS_EHCI=y
1766CONFIG_USB=y
1767# CONFIG_USB_DEBUG is not set
1768CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
1769
1770#
1771# Miscellaneous USB options
1772#
1773CONFIG_USB_DEVICEFS=y
1774# CONFIG_USB_DEVICE_CLASS is not set
1775# CONFIG_USB_DYNAMIC_MINORS is not set
1776CONFIG_USB_SUSPEND=y
1777# CONFIG_USB_OTG is not set
1778
1779#
1780# USB Host Controller Drivers
1781#
1782# CONFIG_USB_C67X00_HCD is not set
1783CONFIG_USB_EHCI_HCD=y
1784CONFIG_USB_EHCI_ROOT_HUB_TT=y
1785CONFIG_USB_EHCI_TT_NEWSCHED=y
1786CONFIG_USB_ISP116X_HCD=m
1787# CONFIG_USB_ISP1760_HCD is not set
1788CONFIG_USB_OHCI_HCD=y
1789# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
1790# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
1791CONFIG_USB_OHCI_LITTLE_ENDIAN=y
1792CONFIG_USB_UHCI_HCD=y
1793CONFIG_USB_U132_HCD=m
1794CONFIG_USB_SL811_HCD=m
1795# CONFIG_USB_R8A66597_HCD is not set
1796
1797#
1798# USB Device Class drivers
1799#
1800CONFIG_USB_ACM=m
1801CONFIG_USB_PRINTER=m
1802# CONFIG_USB_WDM is not set
1803
1804#
1805# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
1806#
1807
1808#
1809# may also be needed; see USB_STORAGE Help for more information
1810#
1811CONFIG_USB_STORAGE=y
1812# CONFIG_USB_STORAGE_DEBUG is not set
1813CONFIG_USB_STORAGE_DATAFAB=y
1814CONFIG_USB_STORAGE_FREECOM=y
1815CONFIG_USB_STORAGE_ISD200=y
1816CONFIG_USB_STORAGE_DPCM=y
1817CONFIG_USB_STORAGE_USBAT=y
1818CONFIG_USB_STORAGE_SDDR09=y
1819CONFIG_USB_STORAGE_SDDR55=y
1820CONFIG_USB_STORAGE_JUMPSHOT=y
1821CONFIG_USB_STORAGE_ALAUDA=y
1822# CONFIG_USB_STORAGE_ONETOUCH is not set
1823CONFIG_USB_STORAGE_KARMA=y
1824# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
1825# CONFIG_USB_LIBUSUAL is not set
1826
1827#
1828# USB Imaging devices
1829#
1830CONFIG_USB_MDC800=m
1831CONFIG_USB_MICROTEK=m
1832CONFIG_USB_MON=y
1833
1834#
1835# USB port drivers
1836#
1837CONFIG_USB_SERIAL=m
1838CONFIG_USB_EZUSB=y
1839CONFIG_USB_SERIAL_GENERIC=y
1840CONFIG_USB_SERIAL_AIRCABLE=m
1841CONFIG_USB_SERIAL_ARK3116=m
1842CONFIG_USB_SERIAL_BELKIN=m
1843CONFIG_USB_SERIAL_CH341=m
1844CONFIG_USB_SERIAL_WHITEHEAT=m
1845CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
1846CONFIG_USB_SERIAL_CP2101=m
1847CONFIG_USB_SERIAL_CYPRESS_M8=m
1848CONFIG_USB_SERIAL_EMPEG=m
1849CONFIG_USB_SERIAL_FTDI_SIO=m
1850CONFIG_USB_SERIAL_FUNSOFT=m
1851CONFIG_USB_SERIAL_VISOR=m
1852CONFIG_USB_SERIAL_IPAQ=m
1853CONFIG_USB_SERIAL_IR=m
1854CONFIG_USB_SERIAL_EDGEPORT=m
1855CONFIG_USB_SERIAL_EDGEPORT_TI=m
1856CONFIG_USB_SERIAL_GARMIN=m
1857CONFIG_USB_SERIAL_IPW=m
1858CONFIG_USB_SERIAL_IUU=m
1859CONFIG_USB_SERIAL_KEYSPAN_PDA=m
1860CONFIG_USB_SERIAL_KEYSPAN=m
1861CONFIG_USB_SERIAL_KEYSPAN_MPR=y
1862CONFIG_USB_SERIAL_KEYSPAN_USA28=y
1863CONFIG_USB_SERIAL_KEYSPAN_USA28X=y
1864CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y
1865CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y
1866CONFIG_USB_SERIAL_KEYSPAN_USA19=y
1867CONFIG_USB_SERIAL_KEYSPAN_USA18X=y
1868CONFIG_USB_SERIAL_KEYSPAN_USA19W=y
1869CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y
1870CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y
1871CONFIG_USB_SERIAL_KEYSPAN_USA49W=y
1872CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
1873CONFIG_USB_SERIAL_KLSI=m
1874CONFIG_USB_SERIAL_KOBIL_SCT=m
1875CONFIG_USB_SERIAL_MCT_U232=m
1876CONFIG_USB_SERIAL_MOS7720=m
1877CONFIG_USB_SERIAL_MOS7840=m
1878# CONFIG_USB_SERIAL_MOTOROLA is not set
1879CONFIG_USB_SERIAL_NAVMAN=m
1880CONFIG_USB_SERIAL_PL2303=m
1881CONFIG_USB_SERIAL_OTI6858=m
1882# CONFIG_USB_SERIAL_SPCP8X5 is not set
1883CONFIG_USB_SERIAL_HP4X=m
1884CONFIG_USB_SERIAL_SAFE=m
1885CONFIG_USB_SERIAL_SAFE_PADDED=y
1886CONFIG_USB_SERIAL_SIERRAWIRELESS=m
1887CONFIG_USB_SERIAL_TI=m
1888CONFIG_USB_SERIAL_CYBERJACK=m
1889CONFIG_USB_SERIAL_XIRCOM=m
1890CONFIG_USB_SERIAL_OPTION=m
1891CONFIG_USB_SERIAL_OMNINET=m
1892CONFIG_USB_SERIAL_DEBUG=m
1893
1894#
1895# USB Miscellaneous drivers
1896#
1897CONFIG_USB_EMI62=m
1898CONFIG_USB_EMI26=m
1899CONFIG_USB_ADUTUX=m
1900CONFIG_USB_AUERSWALD=m
1901# CONFIG_USB_RIO500 is not set
1902CONFIG_USB_LEGOTOWER=m
1903CONFIG_USB_LCD=m
1904CONFIG_USB_BERRY_CHARGE=m
1905CONFIG_USB_LED=m
1906# CONFIG_USB_CYPRESS_CY7C63 is not set
1907# CONFIG_USB_CYTHERM is not set
1908CONFIG_USB_PHIDGET=m
1909CONFIG_USB_PHIDGETKIT=m
1910CONFIG_USB_PHIDGETMOTORCONTROL=m
1911CONFIG_USB_PHIDGETSERVO=m
1912CONFIG_USB_IDMOUSE=m
1913CONFIG_USB_FTDI_ELAN=m
1914CONFIG_USB_APPLEDISPLAY=m
1915CONFIG_USB_SISUSBVGA=m
1916CONFIG_USB_SISUSBVGA_CON=y
1917CONFIG_USB_LD=m
1918CONFIG_USB_TRANCEVIBRATOR=m
1919CONFIG_USB_IOWARRIOR=m
1920# CONFIG_USB_TEST is not set
1921# CONFIG_USB_ISIGHTFW is not set
1922# CONFIG_USB_GADGET is not set
1923CONFIG_MMC=m
1924# CONFIG_MMC_DEBUG is not set
1925# CONFIG_MMC_UNSAFE_RESUME is not set
1926
1927#
1928# MMC/SD Card Drivers
1929#
1930CONFIG_MMC_BLOCK=m
1931CONFIG_MMC_BLOCK_BOUNCE=y
1932CONFIG_SDIO_UART=m
1933# CONFIG_MMC_TEST is not set
1934
1935#
1936# MMC/SD Host Controller Drivers
1937#
1938CONFIG_MMC_SDHCI=m
1939# CONFIG_MMC_SDHCI_PCI is not set
1940CONFIG_MMC_WBSD=m
1941CONFIG_MMC_TIFM_SD=m
1942CONFIG_MEMSTICK=m
1943CONFIG_MEMSTICK_DEBUG=y
1944
1945#
1946# MemoryStick drivers
1947#
1948# CONFIG_MEMSTICK_UNSAFE_RESUME is not set
1949CONFIG_MSPRO_BLOCK=m
1950
1951#
1952# MemoryStick Host Controller Drivers
1953#
1954# CONFIG_MEMSTICK_TIFM_MS is not set
1955# CONFIG_MEMSTICK_JMICRON_38X is not set
1956CONFIG_NEW_LEDS=y
1957CONFIG_LEDS_CLASS=m
1958
1959#
1960# LED drivers
1961#
1962# CONFIG_LEDS_PCA9532 is not set
1963# CONFIG_LEDS_CLEVO_MAIL is not set
1964# CONFIG_LEDS_PCA955X is not set
1965
1966#
1967# LED Triggers
1968#
1969CONFIG_LEDS_TRIGGERS=y
1970# CONFIG_LEDS_TRIGGER_TIMER is not set
1971# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
1972# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
1973# CONFIG_ACCESSIBILITY is not set
1974# CONFIG_INFINIBAND is not set
1975# CONFIG_EDAC is not set
1976CONFIG_RTC_LIB=y
1977CONFIG_RTC_CLASS=y
1978# CONFIG_RTC_HCTOSYS is not set
1979# CONFIG_RTC_DEBUG is not set
1980
1981#
1982# RTC interfaces
1983#
1984CONFIG_RTC_INTF_SYSFS=y
1985CONFIG_RTC_INTF_PROC=y
1986CONFIG_RTC_INTF_DEV=y
1987# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
1988# CONFIG_RTC_DRV_TEST is not set
1989
1990#
1991# I2C RTC drivers
1992#
1993# CONFIG_RTC_DRV_DS1307 is not set
1994# CONFIG_RTC_DRV_DS1374 is not set
1995# CONFIG_RTC_DRV_DS1672 is not set
1996# CONFIG_RTC_DRV_MAX6900 is not set
1997# CONFIG_RTC_DRV_RS5C372 is not set
1998# CONFIG_RTC_DRV_ISL1208 is not set
1999# CONFIG_RTC_DRV_X1205 is not set
2000# CONFIG_RTC_DRV_PCF8563 is not set
2001# CONFIG_RTC_DRV_PCF8583 is not set
2002# CONFIG_RTC_DRV_M41T80 is not set
2003# CONFIG_RTC_DRV_S35390A is not set
2004# CONFIG_RTC_DRV_FM3130 is not set
2005
2006#
2007# SPI RTC drivers
2008#
2009
2010#
2011# Platform RTC drivers
2012#
2013CONFIG_RTC_DRV_CMOS=y
2014# CONFIG_RTC_DRV_DS1511 is not set
2015# CONFIG_RTC_DRV_DS1553 is not set
2016# CONFIG_RTC_DRV_DS1742 is not set
2017# CONFIG_RTC_DRV_STK17TA8 is not set
2018# CONFIG_RTC_DRV_M48T86 is not set
2019# CONFIG_RTC_DRV_M48T59 is not set
2020# CONFIG_RTC_DRV_V3020 is not set
2021
2022#
2023# on-CPU RTC drivers
2024#
2025# CONFIG_DMADEVICES is not set
2026# CONFIG_UIO is not set
2027
2028#
2029# Firmware Drivers
2030#
2031# CONFIG_EDD is not set
2032CONFIG_FIRMWARE_MEMMAP=y
2033# CONFIG_DELL_RBU is not set
2034# CONFIG_DCDBAS is not set
2035# CONFIG_DMIID is not set
2036# CONFIG_ISCSI_IBFT_FIND is not set
2037
2038#
2039# File systems
2040#
2041# CONFIG_EXT2_FS is not set
2042CONFIG_EXT3_FS=y
2043CONFIG_EXT3_FS_XATTR=y
2044CONFIG_EXT3_FS_POSIX_ACL=y
2045CONFIG_EXT3_FS_SECURITY=y
2046# CONFIG_EXT4DEV_FS is not set
2047CONFIG_JBD=y
2048# CONFIG_JBD_DEBUG is not set
2049CONFIG_FS_MBCACHE=y
2050# CONFIG_REISERFS_FS is not set
2051# CONFIG_JFS_FS is not set
2052CONFIG_FS_POSIX_ACL=y
2053# CONFIG_XFS_FS is not set
2054# CONFIG_OCFS2_FS is not set
2055CONFIG_DNOTIFY=y
2056CONFIG_INOTIFY=y
2057CONFIG_INOTIFY_USER=y
2058CONFIG_QUOTA=y
2059CONFIG_QUOTA_NETLINK_INTERFACE=y
2060# CONFIG_PRINT_QUOTA_WARNING is not set
2061# CONFIG_QFMT_V1 is not set
2062CONFIG_QFMT_V2=y
2063CONFIG_QUOTACTL=y
2064# CONFIG_AUTOFS_FS is not set
2065# CONFIG_AUTOFS4_FS is not set
2066CONFIG_FUSE_FS=m
2067CONFIG_GENERIC_ACL=y
2068
2069#
2070# CD-ROM/DVD Filesystems
2071#
2072CONFIG_ISO9660_FS=y
2073CONFIG_JOLIET=y
2074CONFIG_ZISOFS=y
2075CONFIG_UDF_FS=m
2076CONFIG_UDF_NLS=y
2077
2078#
2079# DOS/FAT/NT Filesystems
2080#
2081CONFIG_FAT_FS=y
2082CONFIG_MSDOS_FS=y
2083CONFIG_VFAT_FS=y
2084CONFIG_FAT_DEFAULT_CODEPAGE=437
2085CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
2086# CONFIG_NTFS_FS is not set
2087
2088#
2089# Pseudo filesystems
2090#
2091CONFIG_PROC_FS=y
2092CONFIG_PROC_KCORE=y
2093CONFIG_PROC_VMCORE=y
2094CONFIG_PROC_SYSCTL=y
2095CONFIG_SYSFS=y
2096CONFIG_TMPFS=y
2097CONFIG_TMPFS_POSIX_ACL=y
2098CONFIG_HUGETLBFS=y
2099CONFIG_HUGETLB_PAGE=y
2100CONFIG_CONFIGFS_FS=m
2101
2102#
2103# Layered filesystems
2104#
2105# CONFIG_ECRYPT_FS is not set
2106CONFIG_UNION_FS=y
2107# CONFIG_UNION_FS_XATTR is not set
2108# CONFIG_UNION_FS_DEBUG is not set
2109
2110#
2111# Miscellaneous filesystems
2112#
2113# CONFIG_ADFS_FS is not set
2114# CONFIG_AFFS_FS is not set
2115# CONFIG_HFS_FS is not set
2116# CONFIG_HFSPLUS_FS is not set
2117# CONFIG_BEFS_FS is not set
2118# CONFIG_BFS_FS is not set
2119# CONFIG_EFS_FS is not set
2120# CONFIG_CRAMFS is not set
2121CONFIG_SQUASHFS=y
2122# CONFIG_SQUASHFS_EMBEDDED is not set
2123CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
2124# CONFIG_VXFS_FS is not set
2125# CONFIG_MINIX_FS is not set
2126# CONFIG_OMFS_FS is not set
2127# CONFIG_HPFS_FS is not set
2128# CONFIG_QNX4FS_FS is not set
2129# CONFIG_ROMFS_FS is not set
2130# CONFIG_SYSV_FS is not set
2131# CONFIG_UFS_FS is not set
2132CONFIG_NETWORK_FILESYSTEMS=y
2133# CONFIG_NFS_FS is not set
2134# CONFIG_NFSD is not set
2135# CONFIG_SMB_FS is not set
2136# CONFIG_CIFS is not set
2137# CONFIG_NCP_FS is not set
2138# CONFIG_CODA_FS is not set
2139# CONFIG_AFS_FS is not set
2140
2141#
2142# Partition Types
2143#
2144CONFIG_PARTITION_ADVANCED=y
2145# CONFIG_ACORN_PARTITION is not set
2146CONFIG_OSF_PARTITION=y
2147CONFIG_AMIGA_PARTITION=y
2148# CONFIG_ATARI_PARTITION is not set
2149CONFIG_MAC_PARTITION=y
2150CONFIG_MSDOS_PARTITION=y
2151CONFIG_BSD_DISKLABEL=y
2152CONFIG_MINIX_SUBPARTITION=y
2153CONFIG_SOLARIS_X86_PARTITION=y
2154CONFIG_UNIXWARE_DISKLABEL=y
2155# CONFIG_LDM_PARTITION is not set
2156CONFIG_SGI_PARTITION=y
2157# CONFIG_ULTRIX_PARTITION is not set
2158CONFIG_SUN_PARTITION=y
2159CONFIG_KARMA_PARTITION=y
2160CONFIG_EFI_PARTITION=y
2161# CONFIG_SYSV68_PARTITION is not set
2162CONFIG_NLS=y
2163CONFIG_NLS_DEFAULT="utf8"
2164CONFIG_NLS_CODEPAGE_437=y
2165CONFIG_NLS_CODEPAGE_737=m
2166CONFIG_NLS_CODEPAGE_775=m
2167CONFIG_NLS_CODEPAGE_850=m
2168CONFIG_NLS_CODEPAGE_852=m
2169CONFIG_NLS_CODEPAGE_855=m
2170CONFIG_NLS_CODEPAGE_857=m
2171CONFIG_NLS_CODEPAGE_860=m
2172CONFIG_NLS_CODEPAGE_861=m
2173CONFIG_NLS_CODEPAGE_862=m
2174CONFIG_NLS_CODEPAGE_863=m
2175CONFIG_NLS_CODEPAGE_864=m
2176CONFIG_NLS_CODEPAGE_865=m
2177CONFIG_NLS_CODEPAGE_866=m
2178CONFIG_NLS_CODEPAGE_869=m
2179CONFIG_NLS_CODEPAGE_936=m
2180CONFIG_NLS_CODEPAGE_950=m
2181CONFIG_NLS_CODEPAGE_932=m
2182CONFIG_NLS_CODEPAGE_949=m
2183CONFIG_NLS_CODEPAGE_874=m
2184CONFIG_NLS_ISO8859_8=m
2185CONFIG_NLS_CODEPAGE_1250=m
2186CONFIG_NLS_CODEPAGE_1251=m
2187CONFIG_NLS_ASCII=y
2188CONFIG_NLS_ISO8859_1=m
2189CONFIG_NLS_ISO8859_2=m
2190CONFIG_NLS_ISO8859_3=m
2191CONFIG_NLS_ISO8859_4=m
2192CONFIG_NLS_ISO8859_5=m
2193CONFIG_NLS_ISO8859_6=m
2194CONFIG_NLS_ISO8859_7=m
2195CONFIG_NLS_ISO8859_9=m
2196CONFIG_NLS_ISO8859_13=m
2197CONFIG_NLS_ISO8859_14=m
2198CONFIG_NLS_ISO8859_15=m
2199CONFIG_NLS_KOI8_R=m
2200CONFIG_NLS_KOI8_U=m
2201CONFIG_NLS_UTF8=m
2202# CONFIG_DLM is not set
2203
2204#
2205# Kernel hacking
2206#
2207CONFIG_TRACE_IRQFLAGS_SUPPORT=y
2208CONFIG_PRINTK_TIME=y
2209# CONFIG_ENABLE_WARN_DEPRECATED is not set
2210CONFIG_ENABLE_MUST_CHECK=y
2211CONFIG_FRAME_WARN=1024
2212CONFIG_MAGIC_SYSRQ=y
2213CONFIG_UNUSED_SYMBOLS=y
2214CONFIG_DEBUG_FS=y
2215# CONFIG_HEADERS_CHECK is not set
2216CONFIG_DEBUG_KERNEL=y
2217CONFIG_DEBUG_SHIRQ=y
2218CONFIG_DETECT_SOFTLOCKUP=y
2219# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
2220CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
2221CONFIG_SCHED_DEBUG=y
2222CONFIG_SCHEDSTATS=y
2223CONFIG_TIMER_STATS=y
2224# CONFIG_DEBUG_OBJECTS is not set
2225# CONFIG_DEBUG_SLAB is not set
2226# CONFIG_DEBUG_RT_MUTEXES is not set
2227# CONFIG_RT_MUTEX_TESTER is not set
2228# CONFIG_DEBUG_SPINLOCK is not set
2229# CONFIG_DEBUG_MUTEXES is not set
2230# CONFIG_DEBUG_LOCK_ALLOC is not set
2231# CONFIG_PROVE_LOCKING is not set
2232# CONFIG_LOCK_STAT is not set
2233CONFIG_DEBUG_SPINLOCK_SLEEP=y
2234# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
2235CONFIG_STACKTRACE=y
2236# CONFIG_DEBUG_KOBJECT is not set
2237# CONFIG_DEBUG_HIGHMEM is not set
2238CONFIG_DEBUG_BUGVERBOSE=y
2239# CONFIG_DEBUG_INFO is not set
2240# CONFIG_DEBUG_VM is not set
2241# CONFIG_DEBUG_WRITECOUNT is not set
2242CONFIG_DEBUG_MEMORY_INIT=y
2243CONFIG_DEBUG_LIST=y
2244# CONFIG_DEBUG_SG is not set
2245CONFIG_FRAME_POINTER=y
2246CONFIG_BOOT_PRINTK_DELAY=y
2247# CONFIG_RCU_TORTURE_TEST is not set
2248# CONFIG_BACKTRACE_SELF_TEST is not set
2249# CONFIG_FAULT_INJECTION is not set
2250CONFIG_LATENCYTOP=y
2251CONFIG_HAVE_FTRACE=y
2252CONFIG_HAVE_DYNAMIC_FTRACE=y
2253CONFIG_TRACING=y
2254# CONFIG_FTRACE is not set
2255# CONFIG_IRQSOFF_TRACER is not set
2256CONFIG_SYSPROF_TRACER=y
2257# CONFIG_SCHED_TRACER is not set
2258# CONFIG_CONTEXT_SWITCH_TRACER is not set
2259# CONFIG_FTRACE_STARTUP_TEST is not set
2260# CONFIG_PROVIDE_OHCI1394_DMA_INIT is not set
2261# CONFIG_SAMPLES is not set
2262CONFIG_HAVE_ARCH_KGDB=y
2263# CONFIG_KGDB is not set
2264# CONFIG_STRICT_DEVMEM is not set
2265CONFIG_X86_VERBOSE_BOOTUP=y
2266CONFIG_EARLY_PRINTK=y
2267# CONFIG_DEBUG_STACKOVERFLOW is not set
2268# CONFIG_DEBUG_STACK_USAGE is not set
2269# CONFIG_DEBUG_PAGEALLOC is not set
2270# CONFIG_DEBUG_PER_CPU_MAPS is not set
2271CONFIG_X86_PTDUMP=y
2272CONFIG_DEBUG_RODATA=y
2273# CONFIG_DEBUG_RODATA_TEST is not set
2274# CONFIG_DEBUG_NX_TEST is not set
2275# CONFIG_4KSTACKS is not set
2276CONFIG_DOUBLEFAULT=y
2277# CONFIG_MMIOTRACE is not set
2278CONFIG_IO_DELAY_TYPE_0X80=0
2279CONFIG_IO_DELAY_TYPE_0XED=1
2280CONFIG_IO_DELAY_TYPE_UDELAY=2
2281CONFIG_IO_DELAY_TYPE_NONE=3
2282CONFIG_IO_DELAY_0X80=y
2283# CONFIG_IO_DELAY_0XED is not set
2284# CONFIG_IO_DELAY_UDELAY is not set
2285# CONFIG_IO_DELAY_NONE is not set
2286CONFIG_DEFAULT_IO_DELAY_TYPE=0
2287CONFIG_DEBUG_BOOT_PARAMS=y
2288# CONFIG_CPA_DEBUG is not set
2289# CONFIG_OPTIMIZE_INLINING is not set
2290
2291#
2292# Security options
2293#
2294CONFIG_KEYS=y
2295CONFIG_KEYS_DEBUG_PROC_KEYS=y
2296CONFIG_SECURITY=y
2297CONFIG_SECURITY_NETWORK=y
2298CONFIG_SECURITY_NETWORK_XFRM=y
2299CONFIG_SECURITY_FILE_CAPABILITIES=y
2300# CONFIG_SECURITY_ROOTPLUG is not set
2301CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=65536
2302# CONFIG_SECURITY_SELINUX is not set
2303# CONFIG_SECURITY_SMACK is not set
2304CONFIG_CRYPTO=y
2305
2306#
2307# Crypto core or helper
2308#
2309CONFIG_CRYPTO_ALGAPI=y
2310CONFIG_CRYPTO_AEAD=m
2311CONFIG_CRYPTO_BLKCIPHER=m
2312CONFIG_CRYPTO_HASH=y
2313CONFIG_CRYPTO_MANAGER=y
2314CONFIG_CRYPTO_GF128MUL=m
2315CONFIG_CRYPTO_NULL=m
2316# CONFIG_CRYPTO_CRYPTD is not set
2317CONFIG_CRYPTO_AUTHENC=m
2318CONFIG_CRYPTO_TEST=m
2319
2320#
2321# Authenticated Encryption with Associated Data
2322#
2323CONFIG_CRYPTO_CCM=m
2324CONFIG_CRYPTO_GCM=m
2325CONFIG_CRYPTO_SEQIV=m
2326
2327#
2328# Block modes
2329#
2330CONFIG_CRYPTO_CBC=m
2331CONFIG_CRYPTO_CTR=m
2332# CONFIG_CRYPTO_CTS is not set
2333CONFIG_CRYPTO_ECB=m
2334CONFIG_CRYPTO_LRW=m
2335CONFIG_CRYPTO_PCBC=m
2336CONFIG_CRYPTO_XTS=m
2337
2338#
2339# Hash modes
2340#
2341CONFIG_CRYPTO_HMAC=y
2342CONFIG_CRYPTO_XCBC=m
2343
2344#
2345# Digest
2346#
2347CONFIG_CRYPTO_CRC32C=m
2348CONFIG_CRYPTO_MD4=m
2349CONFIG_CRYPTO_MD5=y
2350CONFIG_CRYPTO_MICHAEL_MIC=m
2351# CONFIG_CRYPTO_RMD128 is not set
2352# CONFIG_CRYPTO_RMD160 is not set
2353# CONFIG_CRYPTO_RMD256 is not set
2354# CONFIG_CRYPTO_RMD320 is not set
2355CONFIG_CRYPTO_SHA1=y
2356CONFIG_CRYPTO_SHA256=m
2357CONFIG_CRYPTO_SHA512=m
2358CONFIG_CRYPTO_TGR192=m
2359CONFIG_CRYPTO_WP512=m
2360
2361#
2362# Ciphers
2363#
2364CONFIG_CRYPTO_AES=m
2365# CONFIG_CRYPTO_AES_586 is not set
2366CONFIG_CRYPTO_ANUBIS=m
2367CONFIG_CRYPTO_ARC4=m
2368CONFIG_CRYPTO_BLOWFISH=m
2369CONFIG_CRYPTO_CAMELLIA=m
2370CONFIG_CRYPTO_CAST5=m
2371CONFIG_CRYPTO_CAST6=m
2372CONFIG_CRYPTO_DES=m
2373CONFIG_CRYPTO_FCRYPT=m
2374CONFIG_CRYPTO_KHAZAD=m
2375CONFIG_CRYPTO_SALSA20=m
2376# CONFIG_CRYPTO_SALSA20_586 is not set
2377CONFIG_CRYPTO_SEED=m
2378CONFIG_CRYPTO_SERPENT=m
2379CONFIG_CRYPTO_TEA=m
2380CONFIG_CRYPTO_TWOFISH=m
2381CONFIG_CRYPTO_TWOFISH_COMMON=m
2382# CONFIG_CRYPTO_TWOFISH_586 is not set
2383
2384#
2385# Compression
2386#
2387CONFIG_CRYPTO_DEFLATE=m
2388# CONFIG_CRYPTO_LZO is not set
2389CONFIG_CRYPTO_HW=y
2390# CONFIG_CRYPTO_DEV_PADLOCK is not set
2391# CONFIG_CRYPTO_DEV_GEODE is not set
2392# CONFIG_CRYPTO_DEV_HIFN_795X is not set
2393CONFIG_HAVE_KVM=y
2394# CONFIG_VIRTUALIZATION is not set
2395
2396#
2397# Library routines
2398#
2399CONFIG_BITREVERSE=y
2400CONFIG_GENERIC_FIND_FIRST_BIT=y
2401CONFIG_GENERIC_FIND_NEXT_BIT=y
2402CONFIG_CRC_CCITT=m
2403CONFIG_CRC16=m
2404CONFIG_CRC_T10DIF=y
2405CONFIG_CRC_ITU_T=m
2406CONFIG_CRC32=y
2407# CONFIG_CRC7 is not set
2408CONFIG_LIBCRC32C=m
2409CONFIG_AUDIT_GENERIC=y
2410CONFIG_ZLIB_INFLATE=y
2411CONFIG_ZLIB_DEFLATE=m
2412CONFIG_TEXTSEARCH=y
2413CONFIG_TEXTSEARCH_KMP=m
2414CONFIG_TEXTSEARCH_BM=m
2415CONFIG_TEXTSEARCH_FSM=m
2416CONFIG_PLIST=y
2417CONFIG_HAS_IOMEM=y
2418CONFIG_HAS_IOPORT=y
2419CONFIG_HAS_DMA=y
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0001-drm-remove-define-for-non-linux-systems.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0001-drm-remove-define-for-non-linux-systems.patch
new file mode 100644
index 0000000000..588c1af70b
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0001-drm-remove-define-for-non-linux-systems.patch
@@ -0,0 +1,48 @@
1commit 2e6ec7cdc09f36be1cbe9aeaccfc45f307fc0060
2Author: Carlos R. Mafra <crmafra2@gmail.com>
3Date: Wed Jul 30 12:29:37 2008 -0700
4
5 drm: remove #define's for non-linux systems
6
7 There is no point in considering FreeBSD et al. in the linux kernel
8 source code.
9
10 Signed-off-by: Carlos R. Mafra <crmafra@gmail.com>
11 Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
12 Signed-off-by: Dave Airlie <airlied@redhat.com>
13
14diff --git a/include/drm/drm.h b/include/drm/drm.h
15index 38d3c6b..0864c69 100644
16--- a/include/drm/drm.h
17+++ b/include/drm/drm.h
18@@ -36,7 +36,6 @@
19 #ifndef _DRM_H_
20 #define _DRM_H_
21
22-#if defined(__linux__)
23 #if defined(__KERNEL__)
24 #endif
25 #include <asm/ioctl.h> /* For _IO* macros */
26@@ -46,22 +45,6 @@
27 #define DRM_IOC_WRITE _IOC_WRITE
28 #define DRM_IOC_READWRITE _IOC_READ|_IOC_WRITE
29 #define DRM_IOC(dir, group, nr, size) _IOC(dir, group, nr, size)
30-#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
31-#if defined(__FreeBSD__) && defined(IN_MODULE)
32-/* Prevent name collision when including sys/ioccom.h */
33-#undef ioctl
34-#include <sys/ioccom.h>
35-#define ioctl(a,b,c) xf86ioctl(a,b,c)
36-#else
37-#include <sys/ioccom.h>
38-#endif /* __FreeBSD__ && xf86ioctl */
39-#define DRM_IOCTL_NR(n) ((n) & 0xff)
40-#define DRM_IOC_VOID IOC_VOID
41-#define DRM_IOC_READ IOC_OUT
42-#define DRM_IOC_WRITE IOC_IN
43-#define DRM_IOC_READWRITE IOC_INOUT
44-#define DRM_IOC(dir, group, nr, size) _IOC(dir, group, nr, size)
45-#endif
46
47 #define DRM_MAJOR 226
48 #define DRM_MAX_MINOR 15
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0002-i915-remove-settable-use_mi_batchbuffer_start.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0002-i915-remove-settable-use_mi_batchbuffer_start.patch
new file mode 100644
index 0000000000..f3c41f7cbd
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0002-i915-remove-settable-use_mi_batchbuffer_start.patch
@@ -0,0 +1,60 @@
1commit 91019197abbfde388d0b71b0fc8979a936c23fe3
2Author: Keith Packard <keithp@keithp.com>
3Date: Wed Jul 30 12:28:47 2008 -0700
4
5 i915: remove settable use_mi_batchbuffer_start
6
7 The driver can know what hardware requires MI_BATCH_BUFFER vs
8 MI_BATCH_BUFFER_START; there's no reason to let user mode configure this.
9
10 Signed-off-by: Eric Anholt <eric@anholt.net>
11 Signed-off-by: Dave Airlie <airlied@redhat.com>
12
13diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
14index 8897434..24adbde 100644
15--- a/drivers/gpu/drm/i915/i915_dma.c
16+++ b/drivers/gpu/drm/i915/i915_dma.c
17@@ -159,13 +159,6 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
18 dev_priv->current_page = 0;
19 dev_priv->sarea_priv->pf_current_page = dev_priv->current_page;
20
21- /* We are using separate values as placeholders for mechanisms for
22- * private backbuffer/depthbuffer usage.
23- */
24- dev_priv->use_mi_batchbuffer_start = 0;
25- if (IS_I965G(dev)) /* 965 doesn't support older method */
26- dev_priv->use_mi_batchbuffer_start = 1;
27-
28 /* Allow hardware batchbuffers unless told otherwise.
29 */
30 dev_priv->allow_batchbuffer = 1;
31@@ -486,7 +479,7 @@ static int i915_dispatch_batchbuffer(struct drm_device * dev,
32 return ret;
33 }
34
35- if (dev_priv->use_mi_batchbuffer_start) {
36+ if (!IS_I830(dev) && !IS_845G(dev)) {
37 BEGIN_LP_RING(2);
38 if (IS_I965G(dev)) {
39 OUT_RING(MI_BATCH_BUFFER_START | (2 << 6) | MI_BATCH_NON_SECURE_I965);
40@@ -697,8 +690,6 @@ static int i915_setparam(struct drm_device *dev, void *data,
41
42 switch (param->param) {
43 case I915_SETPARAM_USE_MI_BATCHBUFFER_START:
44- if (!IS_I965G(dev))
45- dev_priv->use_mi_batchbuffer_start = param->value;
46 break;
47 case I915_SETPARAM_TEX_LRU_LOG_GRANULARITY:
48 dev_priv->tex_lru_log_granularity = param->value;
49diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
50index d7326d9..2d441d3 100644
51--- a/drivers/gpu/drm/i915/i915_drv.h
52+++ b/drivers/gpu/drm/i915/i915_drv.h
53@@ -99,7 +99,6 @@ typedef struct drm_i915_private {
54 int front_offset;
55 int current_page;
56 int page_flipping;
57- int use_mi_batchbuffer_start;
58
59 wait_queue_head_t irq_queue;
60 atomic_t irq_received;
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0003-i915-Ignore-X-server-provided-mmio-address.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0003-i915-Ignore-X-server-provided-mmio-address.patch
new file mode 100644
index 0000000000..9f7e0b4bcd
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0003-i915-Ignore-X-server-provided-mmio-address.patch
@@ -0,0 +1,41 @@
1commit 20ae3cf7d4a9ae8d23bcffa67c9a34fc2640d217
2Author: Keith Packard <keithp@keithp.com>
3Date: Wed Jul 30 12:36:08 2008 -0700
4
5 i915: Ignore X server provided mmio address
6
7 It is already correctly detected by the kernel for use in suspend/resume.
8
9 Signed-off-by: Eric Anholt <eric@anholt.net>
10 Signed-off-by: Dave Airlie <airlied@redhat.com>
11
12diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
13index 24adbde..01a869b 100644
14--- a/drivers/gpu/drm/i915/i915_dma.c
15+++ b/drivers/gpu/drm/i915/i915_dma.c
16@@ -121,13 +121,6 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
17 return -EINVAL;
18 }
19
20- dev_priv->mmio_map = drm_core_findmap(dev, init->mmio_offset);
21- if (!dev_priv->mmio_map) {
22- i915_dma_cleanup(dev);
23- DRM_ERROR("can not find mmio map!\n");
24- return -EINVAL;
25- }
26-
27 dev_priv->sarea_priv = (drm_i915_sarea_t *)
28 ((u8 *) dev_priv->sarea->handle + init->sarea_priv_offset);
29
30@@ -194,11 +187,6 @@ static int i915_dma_resume(struct drm_device * dev)
31 return -EINVAL;
32 }
33
34- if (!dev_priv->mmio_map) {
35- DRM_ERROR("can not find mmio map!\n");
36- return -EINVAL;
37- }
38-
39 if (dev_priv->ring.map.handle == NULL) {
40 DRM_ERROR("can not ioremap virtual address for"
41 " ring buffer\n");
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0004-i915-Use-more-consistent-names-for-regs-and-store.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0004-i915-Use-more-consistent-names-for-regs-and-store.patch
new file mode 100644
index 0000000000..f7a310ea60
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0004-i915-Use-more-consistent-names-for-regs-and-store.patch
@@ -0,0 +1,2746 @@
1commit 573e91575687018b4307f53a50f4da0084dbdf3d
2Author: Jesse Barnes <jbarnes@virtuousgeek.org>
3Date: Tue Jul 29 11:54:06 2008 -0700
4
5 i915: Use more consistent names for regs, and store them in a separate file.
6
7 Signed-off-by: Eric Anholt <eric@anholt.net>
8 Signed-off-by: Dave Airlie <airlied@redhat.com>
9
10diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
11index 01a869b..7be580b 100644
12--- a/drivers/gpu/drm/i915/i915_dma.c
13+++ b/drivers/gpu/drm/i915/i915_dma.c
14@@ -40,11 +40,11 @@ int i915_wait_ring(struct drm_device * dev, int n, const char *caller)
15 {
16 drm_i915_private_t *dev_priv = dev->dev_private;
17 drm_i915_ring_buffer_t *ring = &(dev_priv->ring);
18- u32 last_head = I915_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
19+ u32 last_head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
20 int i;
21
22 for (i = 0; i < 10000; i++) {
23- ring->head = I915_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
24+ ring->head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
25 ring->space = ring->head - (ring->tail + 8);
26 if (ring->space < 0)
27 ring->space += ring->Size;
28@@ -67,8 +67,8 @@ void i915_kernel_lost_context(struct drm_device * dev)
29 drm_i915_private_t *dev_priv = dev->dev_private;
30 drm_i915_ring_buffer_t *ring = &(dev_priv->ring);
31
32- ring->head = I915_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
33- ring->tail = I915_READ(LP_RING + RING_TAIL) & TAIL_ADDR;
34+ ring->head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
35+ ring->tail = I915_READ(PRB0_TAIL) & TAIL_ADDR;
36 ring->space = ring->head - (ring->tail + 8);
37 if (ring->space < 0)
38 ring->space += ring->Size;
39@@ -98,13 +98,13 @@ static int i915_dma_cleanup(struct drm_device * dev)
40 drm_pci_free(dev, dev_priv->status_page_dmah);
41 dev_priv->status_page_dmah = NULL;
42 /* Need to rewrite hardware status page */
43- I915_WRITE(0x02080, 0x1ffff000);
44+ I915_WRITE(HWS_PGA, 0x1ffff000);
45 }
46
47 if (dev_priv->status_gfx_addr) {
48 dev_priv->status_gfx_addr = 0;
49 drm_core_ioremapfree(&dev_priv->hws_map, dev);
50- I915_WRITE(0x2080, 0x1ffff000);
51+ I915_WRITE(HWS_PGA, 0x1ffff000);
52 }
53
54 return 0;
55@@ -170,7 +170,7 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
56 dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr;
57
58 memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
59- I915_WRITE(0x02080, dev_priv->dma_status_page);
60+ I915_WRITE(HWS_PGA, dev_priv->dma_status_page);
61 }
62 DRM_DEBUG("Enabled hardware status page\n");
63 return 0;
64@@ -201,9 +201,9 @@ static int i915_dma_resume(struct drm_device * dev)
65 DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page);
66
67 if (dev_priv->status_gfx_addr != 0)
68- I915_WRITE(0x02080, dev_priv->status_gfx_addr);
69+ I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr);
70 else
71- I915_WRITE(0x02080, dev_priv->dma_status_page);
72+ I915_WRITE(HWS_PGA, dev_priv->dma_status_page);
73 DRM_DEBUG("Enabled hardware status page\n");
74
75 return 0;
76@@ -402,8 +402,8 @@ static void i915_emit_breadcrumb(struct drm_device *dev)
77 dev_priv->sarea_priv->last_enqueue = dev_priv->counter = 1;
78
79 BEGIN_LP_RING(4);
80- OUT_RING(CMD_STORE_DWORD_IDX);
81- OUT_RING(20);
82+ OUT_RING(MI_STORE_DWORD_INDEX);
83+ OUT_RING(5 << MI_STORE_DWORD_INDEX_SHIFT);
84 OUT_RING(dev_priv->counter);
85 OUT_RING(0);
86 ADVANCE_LP_RING();
87@@ -505,7 +505,7 @@ static int i915_dispatch_flip(struct drm_device * dev)
88 i915_kernel_lost_context(dev);
89
90 BEGIN_LP_RING(2);
91- OUT_RING(INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE);
92+ OUT_RING(MI_FLUSH | MI_READ_FLUSH);
93 OUT_RING(0);
94 ADVANCE_LP_RING();
95
96@@ -530,8 +530,8 @@ static int i915_dispatch_flip(struct drm_device * dev)
97 dev_priv->sarea_priv->last_enqueue = dev_priv->counter++;
98
99 BEGIN_LP_RING(4);
100- OUT_RING(CMD_STORE_DWORD_IDX);
101- OUT_RING(20);
102+ OUT_RING(MI_STORE_DWORD_INDEX);
103+ OUT_RING(5 << MI_STORE_DWORD_INDEX_SHIFT);
104 OUT_RING(dev_priv->counter);
105 OUT_RING(0);
106 ADVANCE_LP_RING();
107@@ -728,8 +728,8 @@ static int i915_set_status_page(struct drm_device *dev, void *data,
108 dev_priv->hw_status_page = dev_priv->hws_map.handle;
109
110 memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
111- I915_WRITE(0x02080, dev_priv->status_gfx_addr);
112- DRM_DEBUG("load hws 0x2080 with gfx mem 0x%x\n",
113+ I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr);
114+ DRM_DEBUG("load hws HWS_PGA with gfx mem 0x%x\n",
115 dev_priv->status_gfx_addr);
116 DRM_DEBUG("load hws at %p\n", dev_priv->hw_status_page);
117 return 0;
118diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
119index 93aed1c..6c99aab 100644
120--- a/drivers/gpu/drm/i915/i915_drv.c
121+++ b/drivers/gpu/drm/i915/i915_drv.c
122@@ -279,13 +279,13 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state)
123 dev_priv->saveDSPASTRIDE = I915_READ(DSPASTRIDE);
124 dev_priv->saveDSPASIZE = I915_READ(DSPASIZE);
125 dev_priv->saveDSPAPOS = I915_READ(DSPAPOS);
126- dev_priv->saveDSPABASE = I915_READ(DSPABASE);
127+ dev_priv->saveDSPAADDR = I915_READ(DSPAADDR);
128 if (IS_I965G(dev)) {
129 dev_priv->saveDSPASURF = I915_READ(DSPASURF);
130 dev_priv->saveDSPATILEOFF = I915_READ(DSPATILEOFF);
131 }
132 i915_save_palette(dev, PIPE_A);
133- dev_priv->savePIPEASTAT = I915_READ(I915REG_PIPEASTAT);
134+ dev_priv->savePIPEASTAT = I915_READ(PIPEASTAT);
135
136 /* Pipe & plane B info */
137 dev_priv->savePIPEBCONF = I915_READ(PIPEBCONF);
138@@ -307,13 +307,13 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state)
139 dev_priv->saveDSPBSTRIDE = I915_READ(DSPBSTRIDE);
140 dev_priv->saveDSPBSIZE = I915_READ(DSPBSIZE);
141 dev_priv->saveDSPBPOS = I915_READ(DSPBPOS);
142- dev_priv->saveDSPBBASE = I915_READ(DSPBBASE);
143+ dev_priv->saveDSPBADDR = I915_READ(DSPBADDR);
144 if (IS_I965GM(dev) || IS_IGD_GM(dev)) {
145 dev_priv->saveDSPBSURF = I915_READ(DSPBSURF);
146 dev_priv->saveDSPBTILEOFF = I915_READ(DSPBTILEOFF);
147 }
148 i915_save_palette(dev, PIPE_B);
149- dev_priv->savePIPEBSTAT = I915_READ(I915REG_PIPEBSTAT);
150+ dev_priv->savePIPEBSTAT = I915_READ(PIPEBSTAT);
151
152 /* CRT state */
153 dev_priv->saveADPA = I915_READ(ADPA);
154@@ -328,9 +328,9 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state)
155 dev_priv->saveLVDS = I915_READ(LVDS);
156 if (!IS_I830(dev) && !IS_845G(dev))
157 dev_priv->savePFIT_CONTROL = I915_READ(PFIT_CONTROL);
158- dev_priv->saveLVDSPP_ON = I915_READ(LVDSPP_ON);
159- dev_priv->saveLVDSPP_OFF = I915_READ(LVDSPP_OFF);
160- dev_priv->savePP_CYCLE = I915_READ(PP_CYCLE);
161+ dev_priv->savePP_ON_DELAYS = I915_READ(PP_ON_DELAYS);
162+ dev_priv->savePP_OFF_DELAYS = I915_READ(PP_OFF_DELAYS);
163+ dev_priv->savePP_DIVISOR = I915_READ(PP_DIVISOR);
164
165 /* FIXME: save TV & SDVO state */
166
167@@ -341,19 +341,19 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state)
168 dev_priv->saveFBC_CONTROL = I915_READ(FBC_CONTROL);
169
170 /* Interrupt state */
171- dev_priv->saveIIR = I915_READ(I915REG_INT_IDENTITY_R);
172- dev_priv->saveIER = I915_READ(I915REG_INT_ENABLE_R);
173- dev_priv->saveIMR = I915_READ(I915REG_INT_MASK_R);
174+ dev_priv->saveIIR = I915_READ(IIR);
175+ dev_priv->saveIER = I915_READ(IER);
176+ dev_priv->saveIMR = I915_READ(IMR);
177
178 /* VGA state */
179- dev_priv->saveVCLK_DIVISOR_VGA0 = I915_READ(VCLK_DIVISOR_VGA0);
180- dev_priv->saveVCLK_DIVISOR_VGA1 = I915_READ(VCLK_DIVISOR_VGA1);
181- dev_priv->saveVCLK_POST_DIV = I915_READ(VCLK_POST_DIV);
182+ dev_priv->saveVGA0 = I915_READ(VGA0);
183+ dev_priv->saveVGA1 = I915_READ(VGA1);
184+ dev_priv->saveVGA_PD = I915_READ(VGA_PD);
185 dev_priv->saveVGACNTRL = I915_READ(VGACNTRL);
186
187 /* Clock gating state */
188 dev_priv->saveD_STATE = I915_READ(D_STATE);
189- dev_priv->saveDSPCLK_GATE_D = I915_READ(DSPCLK_GATE_D);
190+ dev_priv->saveCG_2D_DIS = I915_READ(CG_2D_DIS);
191
192 /* Cache mode state */
193 dev_priv->saveCACHE_MODE_0 = I915_READ(CACHE_MODE_0);
194@@ -363,7 +363,7 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state)
195
196 /* Scratch space */
197 for (i = 0; i < 16; i++) {
198- dev_priv->saveSWF0[i] = I915_READ(SWF0 + (i << 2));
199+ dev_priv->saveSWF0[i] = I915_READ(SWF00 + (i << 2));
200 dev_priv->saveSWF1[i] = I915_READ(SWF10 + (i << 2));
201 }
202 for (i = 0; i < 3; i++)
203@@ -424,7 +424,7 @@ static int i915_resume(struct drm_device *dev)
204 I915_WRITE(DSPASIZE, dev_priv->saveDSPASIZE);
205 I915_WRITE(DSPAPOS, dev_priv->saveDSPAPOS);
206 I915_WRITE(PIPEASRC, dev_priv->savePIPEASRC);
207- I915_WRITE(DSPABASE, dev_priv->saveDSPABASE);
208+ I915_WRITE(DSPAADDR, dev_priv->saveDSPAADDR);
209 I915_WRITE(DSPASTRIDE, dev_priv->saveDSPASTRIDE);
210 if (IS_I965G(dev)) {
211 I915_WRITE(DSPASURF, dev_priv->saveDSPASURF);
212@@ -436,7 +436,7 @@ static int i915_resume(struct drm_device *dev)
213 i915_restore_palette(dev, PIPE_A);
214 /* Enable the plane */
215 I915_WRITE(DSPACNTR, dev_priv->saveDSPACNTR);
216- I915_WRITE(DSPABASE, I915_READ(DSPABASE));
217+ I915_WRITE(DSPAADDR, I915_READ(DSPAADDR));
218
219 /* Pipe & plane B info */
220 if (dev_priv->saveDPLL_B & DPLL_VCO_ENABLE) {
221@@ -466,7 +466,7 @@ static int i915_resume(struct drm_device *dev)
222 I915_WRITE(DSPBSIZE, dev_priv->saveDSPBSIZE);
223 I915_WRITE(DSPBPOS, dev_priv->saveDSPBPOS);
224 I915_WRITE(PIPEBSRC, dev_priv->savePIPEBSRC);
225- I915_WRITE(DSPBBASE, dev_priv->saveDSPBBASE);
226+ I915_WRITE(DSPBADDR, dev_priv->saveDSPBADDR);
227 I915_WRITE(DSPBSTRIDE, dev_priv->saveDSPBSTRIDE);
228 if (IS_I965G(dev)) {
229 I915_WRITE(DSPBSURF, dev_priv->saveDSPBSURF);
230@@ -478,7 +478,7 @@ static int i915_resume(struct drm_device *dev)
231 i915_restore_palette(dev, PIPE_B);
232 /* Enable the plane */
233 I915_WRITE(DSPBCNTR, dev_priv->saveDSPBCNTR);
234- I915_WRITE(DSPBBASE, I915_READ(DSPBBASE));
235+ I915_WRITE(DSPBADDR, I915_READ(DSPBADDR));
236
237 /* CRT state */
238 I915_WRITE(ADPA, dev_priv->saveADPA);
239@@ -493,9 +493,9 @@ static int i915_resume(struct drm_device *dev)
240
241 I915_WRITE(PFIT_PGM_RATIOS, dev_priv->savePFIT_PGM_RATIOS);
242 I915_WRITE(BLC_PWM_CTL, dev_priv->saveBLC_PWM_CTL);
243- I915_WRITE(LVDSPP_ON, dev_priv->saveLVDSPP_ON);
244- I915_WRITE(LVDSPP_OFF, dev_priv->saveLVDSPP_OFF);
245- I915_WRITE(PP_CYCLE, dev_priv->savePP_CYCLE);
246+ I915_WRITE(PP_ON_DELAYS, dev_priv->savePP_ON_DELAYS);
247+ I915_WRITE(PP_OFF_DELAYS, dev_priv->savePP_OFF_DELAYS);
248+ I915_WRITE(PP_DIVISOR, dev_priv->savePP_DIVISOR);
249 I915_WRITE(PP_CONTROL, dev_priv->savePP_CONTROL);
250
251 /* FIXME: restore TV & SDVO state */
252@@ -508,14 +508,14 @@ static int i915_resume(struct drm_device *dev)
253
254 /* VGA state */
255 I915_WRITE(VGACNTRL, dev_priv->saveVGACNTRL);
256- I915_WRITE(VCLK_DIVISOR_VGA0, dev_priv->saveVCLK_DIVISOR_VGA0);
257- I915_WRITE(VCLK_DIVISOR_VGA1, dev_priv->saveVCLK_DIVISOR_VGA1);
258- I915_WRITE(VCLK_POST_DIV, dev_priv->saveVCLK_POST_DIV);
259+ I915_WRITE(VGA0, dev_priv->saveVGA0);
260+ I915_WRITE(VGA1, dev_priv->saveVGA1);
261+ I915_WRITE(VGA_PD, dev_priv->saveVGA_PD);
262 udelay(150);
263
264 /* Clock gating state */
265 I915_WRITE (D_STATE, dev_priv->saveD_STATE);
266- I915_WRITE (DSPCLK_GATE_D, dev_priv->saveDSPCLK_GATE_D);
267+ I915_WRITE(CG_2D_DIS, dev_priv->saveCG_2D_DIS);
268
269 /* Cache mode state */
270 I915_WRITE (CACHE_MODE_0, dev_priv->saveCACHE_MODE_0 | 0xffff0000);
271@@ -524,7 +524,7 @@ static int i915_resume(struct drm_device *dev)
272 I915_WRITE (MI_ARB_STATE, dev_priv->saveMI_ARB_STATE | 0xffff0000);
273
274 for (i = 0; i < 16; i++) {
275- I915_WRITE(SWF0 + (i << 2), dev_priv->saveSWF0[i]);
276+ I915_WRITE(SWF00 + (i << 2), dev_priv->saveSWF0[i]);
277 I915_WRITE(SWF10 + (i << 2), dev_priv->saveSWF1[i+7]);
278 }
279 for (i = 0; i < 3; i++)
280diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
281index 2d441d3..afb51a3 100644
282--- a/drivers/gpu/drm/i915/i915_drv.h
283+++ b/drivers/gpu/drm/i915/i915_drv.h
284@@ -30,6 +30,8 @@
285 #ifndef _I915_DRV_H_
286 #define _I915_DRV_H_
287
288+#include "i915_reg.h"
289+
290 /* General customization:
291 */
292
293@@ -138,7 +140,7 @@ typedef struct drm_i915_private {
294 u32 saveDSPASTRIDE;
295 u32 saveDSPASIZE;
296 u32 saveDSPAPOS;
297- u32 saveDSPABASE;
298+ u32 saveDSPAADDR;
299 u32 saveDSPASURF;
300 u32 saveDSPATILEOFF;
301 u32 savePFIT_PGM_RATIOS;
302@@ -159,24 +161,24 @@ typedef struct drm_i915_private {
303 u32 saveDSPBSTRIDE;
304 u32 saveDSPBSIZE;
305 u32 saveDSPBPOS;
306- u32 saveDSPBBASE;
307+ u32 saveDSPBADDR;
308 u32 saveDSPBSURF;
309 u32 saveDSPBTILEOFF;
310- u32 saveVCLK_DIVISOR_VGA0;
311- u32 saveVCLK_DIVISOR_VGA1;
312- u32 saveVCLK_POST_DIV;
313+ u32 saveVGA0;
314+ u32 saveVGA1;
315+ u32 saveVGA_PD;
316 u32 saveVGACNTRL;
317 u32 saveADPA;
318 u32 saveLVDS;
319- u32 saveLVDSPP_ON;
320- u32 saveLVDSPP_OFF;
321+ u32 savePP_ON_DELAYS;
322+ u32 savePP_OFF_DELAYS;
323 u32 saveDVOA;
324 u32 saveDVOB;
325 u32 saveDVOC;
326 u32 savePP_ON;
327 u32 savePP_OFF;
328 u32 savePP_CONTROL;
329- u32 savePP_CYCLE;
330+ u32 savePP_DIVISOR;
331 u32 savePFIT_CONTROL;
332 u32 save_palette_a[256];
333 u32 save_palette_b[256];
334@@ -189,7 +191,7 @@ typedef struct drm_i915_private {
335 u32 saveIMR;
336 u32 saveCACHE_MODE_0;
337 u32 saveD_STATE;
338- u32 saveDSPCLK_GATE_D;
339+ u32 saveCG_2D_DIS;
340 u32 saveMI_ARB_STATE;
341 u32 saveSWF0[16];
342 u32 saveSWF1[16];
343@@ -283,816 +285,26 @@ extern void i915_mem_release(struct drm_device * dev,
344 if (I915_VERBOSE) DRM_DEBUG("ADVANCE_LP_RING %x\n", outring); \
345 dev_priv->ring.tail = outring; \
346 dev_priv->ring.space -= outcount * 4; \
347- I915_WRITE(LP_RING + RING_TAIL, outring); \
348+ I915_WRITE(PRB0_TAIL, outring); \
349 } while(0)
350
351-extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
352-
353-/* Extended config space */
354-#define LBB 0xf4
355-
356-/* VGA stuff */
357-
358-#define VGA_ST01_MDA 0x3ba
359-#define VGA_ST01_CGA 0x3da
360-
361-#define VGA_MSR_WRITE 0x3c2
362-#define VGA_MSR_READ 0x3cc
363-#define VGA_MSR_MEM_EN (1<<1)
364-#define VGA_MSR_CGA_MODE (1<<0)
365-
366-#define VGA_SR_INDEX 0x3c4
367-#define VGA_SR_DATA 0x3c5
368-
369-#define VGA_AR_INDEX 0x3c0
370-#define VGA_AR_VID_EN (1<<5)
371-#define VGA_AR_DATA_WRITE 0x3c0
372-#define VGA_AR_DATA_READ 0x3c1
373-
374-#define VGA_GR_INDEX 0x3ce
375-#define VGA_GR_DATA 0x3cf
376-/* GR05 */
377-#define VGA_GR_MEM_READ_MODE_SHIFT 3
378-#define VGA_GR_MEM_READ_MODE_PLANE 1
379-/* GR06 */
380-#define VGA_GR_MEM_MODE_MASK 0xc
381-#define VGA_GR_MEM_MODE_SHIFT 2
382-#define VGA_GR_MEM_A0000_AFFFF 0
383-#define VGA_GR_MEM_A0000_BFFFF 1
384-#define VGA_GR_MEM_B0000_B7FFF 2
385-#define VGA_GR_MEM_B0000_BFFFF 3
386-
387-#define VGA_DACMASK 0x3c6
388-#define VGA_DACRX 0x3c7
389-#define VGA_DACWX 0x3c8
390-#define VGA_DACDATA 0x3c9
391-
392-#define VGA_CR_INDEX_MDA 0x3b4
393-#define VGA_CR_DATA_MDA 0x3b5
394-#define VGA_CR_INDEX_CGA 0x3d4
395-#define VGA_CR_DATA_CGA 0x3d5
396-
397-#define GFX_OP_USER_INTERRUPT ((0<<29)|(2<<23))
398-#define GFX_OP_BREAKPOINT_INTERRUPT ((0<<29)|(1<<23))
399-#define CMD_REPORT_HEAD (7<<23)
400-#define CMD_STORE_DWORD_IDX ((0x21<<23) | 0x1)
401-#define CMD_OP_BATCH_BUFFER ((0x0<<29)|(0x30<<23)|0x1)
402-
403-#define INST_PARSER_CLIENT 0x00000000
404-#define INST_OP_FLUSH 0x02000000
405-#define INST_FLUSH_MAP_CACHE 0x00000001
406-
407-#define BB1_START_ADDR_MASK (~0x7)
408-#define BB1_PROTECTED (1<<0)
409-#define BB1_UNPROTECTED (0<<0)
410-#define BB2_END_ADDR_MASK (~0x7)
411-
412-/* Framebuffer compression */
413-#define FBC_CFB_BASE 0x03200 /* 4k page aligned */
414-#define FBC_LL_BASE 0x03204 /* 4k page aligned */
415-#define FBC_CONTROL 0x03208
416-#define FBC_CTL_EN (1<<31)
417-#define FBC_CTL_PERIODIC (1<<30)
418-#define FBC_CTL_INTERVAL_SHIFT (16)
419-#define FBC_CTL_UNCOMPRESSIBLE (1<<14)
420-#define FBC_CTL_STRIDE_SHIFT (5)
421-#define FBC_CTL_FENCENO (1<<0)
422-#define FBC_COMMAND 0x0320c
423-#define FBC_CMD_COMPRESS (1<<0)
424-#define FBC_STATUS 0x03210
425-#define FBC_STAT_COMPRESSING (1<<31)
426-#define FBC_STAT_COMPRESSED (1<<30)
427-#define FBC_STAT_MODIFIED (1<<29)
428-#define FBC_STAT_CURRENT_LINE (1<<0)
429-#define FBC_CONTROL2 0x03214
430-#define FBC_CTL_FENCE_DBL (0<<4)
431-#define FBC_CTL_IDLE_IMM (0<<2)
432-#define FBC_CTL_IDLE_FULL (1<<2)
433-#define FBC_CTL_IDLE_LINE (2<<2)
434-#define FBC_CTL_IDLE_DEBUG (3<<2)
435-#define FBC_CTL_CPU_FENCE (1<<1)
436-#define FBC_CTL_PLANEA (0<<0)
437-#define FBC_CTL_PLANEB (1<<0)
438-#define FBC_FENCE_OFF 0x0321b
439-
440-#define FBC_LL_SIZE (1536)
441-#define FBC_LL_PAD (32)
442-
443-/* Interrupt bits:
444- */
445-#define USER_INT_FLAG (1<<1)
446-#define VSYNC_PIPEB_FLAG (1<<5)
447-#define VSYNC_PIPEA_FLAG (1<<7)
448-#define HWB_OOM_FLAG (1<<13) /* binner out of memory */
449-
450-#define I915REG_HWSTAM 0x02098
451-#define I915REG_INT_IDENTITY_R 0x020a4
452-#define I915REG_INT_MASK_R 0x020a8
453-#define I915REG_INT_ENABLE_R 0x020a0
454-
455-#define I915REG_PIPEASTAT 0x70024
456-#define I915REG_PIPEBSTAT 0x71024
457-
458-#define I915_VBLANK_INTERRUPT_ENABLE (1UL<<17)
459-#define I915_VBLANK_CLEAR (1UL<<1)
460-
461-#define SRX_INDEX 0x3c4
462-#define SRX_DATA 0x3c5
463-#define SR01 1
464-#define SR01_SCREEN_OFF (1<<5)
465-
466-#define PPCR 0x61204
467-#define PPCR_ON (1<<0)
468-
469-#define DVOB 0x61140
470-#define DVOB_ON (1<<31)
471-#define DVOC 0x61160
472-#define DVOC_ON (1<<31)
473-#define LVDS 0x61180
474-#define LVDS_ON (1<<31)
475-
476-#define ADPA 0x61100
477-#define ADPA_DPMS_MASK (~(3<<10))
478-#define ADPA_DPMS_ON (0<<10)
479-#define ADPA_DPMS_SUSPEND (1<<10)
480-#define ADPA_DPMS_STANDBY (2<<10)
481-#define ADPA_DPMS_OFF (3<<10)
482-
483-#define NOPID 0x2094
484-#define LP_RING 0x2030
485-#define HP_RING 0x2040
486-/* The binner has its own ring buffer:
487- */
488-#define HWB_RING 0x2400
489-
490-#define RING_TAIL 0x00
491-#define TAIL_ADDR 0x001FFFF8
492-#define RING_HEAD 0x04
493-#define HEAD_WRAP_COUNT 0xFFE00000
494-#define HEAD_WRAP_ONE 0x00200000
495-#define HEAD_ADDR 0x001FFFFC
496-#define RING_START 0x08
497-#define START_ADDR 0x0xFFFFF000
498-#define RING_LEN 0x0C
499-#define RING_NR_PAGES 0x001FF000
500-#define RING_REPORT_MASK 0x00000006
501-#define RING_REPORT_64K 0x00000002
502-#define RING_REPORT_128K 0x00000004
503-#define RING_NO_REPORT 0x00000000
504-#define RING_VALID_MASK 0x00000001
505-#define RING_VALID 0x00000001
506-#define RING_INVALID 0x00000000
507-
508-/* Instruction parser error reg:
509- */
510-#define IPEIR 0x2088
511-
512-/* Scratch pad debug 0 reg:
513- */
514-#define SCPD0 0x209c
515-
516-/* Error status reg:
517- */
518-#define ESR 0x20b8
519-
520-/* Secondary DMA fetch address debug reg:
521- */
522-#define DMA_FADD_S 0x20d4
523-
524-/* Memory Interface Arbitration State
525- */
526-#define MI_ARB_STATE 0x20e4
527-
528-/* Cache mode 0 reg.
529- * - Manipulating render cache behaviour is central
530- * to the concept of zone rendering, tuning this reg can help avoid
531- * unnecessary render cache reads and even writes (for z/stencil)
532- * at beginning and end of scene.
533- *
534- * - To change a bit, write to this reg with a mask bit set and the
535- * bit of interest either set or cleared. EG: (BIT<<16) | BIT to set.
536- */
537-#define Cache_Mode_0 0x2120
538-#define CACHE_MODE_0 0x2120
539-#define CM0_MASK_SHIFT 16
540-#define CM0_IZ_OPT_DISABLE (1<<6)
541-#define CM0_ZR_OPT_DISABLE (1<<5)
542-#define CM0_DEPTH_EVICT_DISABLE (1<<4)
543-#define CM0_COLOR_EVICT_DISABLE (1<<3)
544-#define CM0_DEPTH_WRITE_DISABLE (1<<1)
545-#define CM0_RC_OP_FLUSH_DISABLE (1<<0)
546-
547-
548-/* Graphics flush control. A CPU write flushes the GWB of all writes.
549- * The data is discarded.
550- */
551-#define GFX_FLSH_CNTL 0x2170
552-
553-/* Binner control. Defines the location of the bin pointer list:
554- */
555-#define BINCTL 0x2420
556-#define BC_MASK (1 << 9)
557-
558-/* Binned scene info.
559- */
560-#define BINSCENE 0x2428
561-#define BS_OP_LOAD (1 << 8)
562-#define BS_MASK (1 << 22)
563-
564-/* Bin command parser debug reg:
565- */
566-#define BCPD 0x2480
567-
568-/* Bin memory control debug reg:
569- */
570-#define BMCD 0x2484
571-
572-/* Bin data cache debug reg:
573- */
574-#define BDCD 0x2488
575-
576-/* Binner pointer cache debug reg:
577- */
578-#define BPCD 0x248c
579-
580-/* Binner scratch pad debug reg:
581- */
582-#define BINSKPD 0x24f0
583-
584-/* HWB scratch pad debug reg:
585- */
586-#define HWBSKPD 0x24f4
587-
588-/* Binner memory pool reg:
589- */
590-#define BMP_BUFFER 0x2430
591-#define BMP_PAGE_SIZE_4K (0 << 10)
592-#define BMP_BUFFER_SIZE_SHIFT 1
593-#define BMP_ENABLE (1 << 0)
594-
595-/* Get/put memory from the binner memory pool:
596- */
597-#define BMP_GET 0x2438
598-#define BMP_PUT 0x2440
599-#define BMP_OFFSET_SHIFT 5
600-
601-/* 3D state packets:
602- */
603-#define GFX_OP_RASTER_RULES ((0x3<<29)|(0x7<<24))
604-
605-#define GFX_OP_SCISSOR ((0x3<<29)|(0x1c<<24)|(0x10<<19))
606-#define SC_UPDATE_SCISSOR (0x1<<1)
607-#define SC_ENABLE_MASK (0x1<<0)
608-#define SC_ENABLE (0x1<<0)
609-
610-#define GFX_OP_LOAD_INDIRECT ((0x3<<29)|(0x1d<<24)|(0x7<<16))
611-
612-#define GFX_OP_SCISSOR_INFO ((0x3<<29)|(0x1d<<24)|(0x81<<16)|(0x1))
613-#define SCI_YMIN_MASK (0xffff<<16)
614-#define SCI_XMIN_MASK (0xffff<<0)
615-#define SCI_YMAX_MASK (0xffff<<16)
616-#define SCI_XMAX_MASK (0xffff<<0)
617-
618-#define GFX_OP_SCISSOR_ENABLE ((0x3<<29)|(0x1c<<24)|(0x10<<19))
619-#define GFX_OP_SCISSOR_RECT ((0x3<<29)|(0x1d<<24)|(0x81<<16)|1)
620-#define GFX_OP_COLOR_FACTOR ((0x3<<29)|(0x1d<<24)|(0x1<<16)|0x0)
621-#define GFX_OP_STIPPLE ((0x3<<29)|(0x1d<<24)|(0x83<<16))
622-#define GFX_OP_MAP_INFO ((0x3<<29)|(0x1d<<24)|0x4)
623-#define GFX_OP_DESTBUFFER_VARS ((0x3<<29)|(0x1d<<24)|(0x85<<16)|0x0)
624-#define GFX_OP_DRAWRECT_INFO ((0x3<<29)|(0x1d<<24)|(0x80<<16)|(0x3))
625-
626-#define GFX_OP_DRAWRECT_INFO_I965 ((0x7900<<16)|0x2)
627-
628-#define SRC_COPY_BLT_CMD ((2<<29)|(0x43<<22)|4)
629-#define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6)
630-#define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21)
631-#define XY_SRC_COPY_BLT_WRITE_RGB (1<<20)
632-#define XY_SRC_COPY_BLT_SRC_TILED (1<<15)
633-#define XY_SRC_COPY_BLT_DST_TILED (1<<11)
634-
635-#define MI_BATCH_BUFFER ((0x30<<23)|1)
636-#define MI_BATCH_BUFFER_START (0x31<<23)
637-#define MI_BATCH_BUFFER_END (0xA<<23)
638-#define MI_BATCH_NON_SECURE (1)
639-#define MI_BATCH_NON_SECURE_I965 (1<<8)
640-
641-#define MI_WAIT_FOR_EVENT ((0x3<<23))
642-#define MI_WAIT_FOR_PLANE_B_FLIP (1<<6)
643-#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2)
644-#define MI_WAIT_FOR_PLANE_A_SCANLINES (1<<1)
645-
646-#define MI_LOAD_SCAN_LINES_INCL ((0x12<<23))
647-
648-#define CMD_OP_DISPLAYBUFFER_INFO ((0x0<<29)|(0x14<<23)|2)
649-#define ASYNC_FLIP (1<<22)
650-#define DISPLAY_PLANE_A (0<<20)
651-#define DISPLAY_PLANE_B (1<<20)
652-
653-/* Display regs */
654-#define DSPACNTR 0x70180
655-#define DSPBCNTR 0x71180
656-#define DISPPLANE_SEL_PIPE_MASK (1<<24)
657-
658-/* Define the region of interest for the binner:
659- */
660-#define CMD_OP_BIN_CONTROL ((0x3<<29)|(0x1d<<24)|(0x84<<16)|4)
661-
662-#define CMD_OP_DESTBUFFER_INFO ((0x3<<29)|(0x1d<<24)|(0x8e<<16)|1)
663-
664-#define CMD_MI_FLUSH (0x04 << 23)
665-#define MI_NO_WRITE_FLUSH (1 << 2)
666-#define MI_READ_FLUSH (1 << 0)
667-#define MI_EXE_FLUSH (1 << 1)
668-#define MI_END_SCENE (1 << 4) /* flush binner and incr scene count */
669-#define MI_SCENE_COUNT (1 << 3) /* just increment scene count */
670-
671-#define BREADCRUMB_BITS 31
672-#define BREADCRUMB_MASK ((1U << BREADCRUMB_BITS) - 1)
673-
674-#define READ_BREADCRUMB(dev_priv) (((volatile u32*)(dev_priv->hw_status_page))[5])
675-#define READ_HWSP(dev_priv, reg) (((volatile u32*)(dev_priv->hw_status_page))[reg])
676-
677-#define BLC_PWM_CTL 0x61254
678-#define BACKLIGHT_MODULATION_FREQ_SHIFT (17)
679-
680-#define BLC_PWM_CTL2 0x61250
681 /**
682- * This is the most significant 15 bits of the number of backlight cycles in a
683- * complete cycle of the modulated backlight control.
684+ * Reads a dword out of the status page, which is written to from the command
685+ * queue by automatic updates, MI_REPORT_HEAD, MI_STORE_DATA_INDEX, or
686+ * MI_STORE_DATA_IMM.
687 *
688- * The actual value is this field multiplied by two.
689- */
690-#define BACKLIGHT_MODULATION_FREQ_MASK (0x7fff << 17)
691-#define BLM_LEGACY_MODE (1 << 16)
692-/**
693- * This is the number of cycles out of the backlight modulation cycle for which
694- * the backlight is on.
695+ * The following dwords have a reserved meaning:
696+ * 0: ISR copy, updated when an ISR bit not set in the HWSTAM changes.
697+ * 4: ring 0 head pointer
698+ * 5: ring 1 head pointer (915-class)
699+ * 6: ring 2 head pointer (915-class)
700 *
701- * This field must be no greater than the number of cycles in the complete
702- * backlight modulation cycle.
703- */
704-#define BACKLIGHT_DUTY_CYCLE_SHIFT (0)
705-#define BACKLIGHT_DUTY_CYCLE_MASK (0xffff)
706-
707-#define I915_GCFGC 0xf0
708-#define I915_LOW_FREQUENCY_ENABLE (1 << 7)
709-#define I915_DISPLAY_CLOCK_190_200_MHZ (0 << 4)
710-#define I915_DISPLAY_CLOCK_333_MHZ (4 << 4)
711-#define I915_DISPLAY_CLOCK_MASK (7 << 4)
712-
713-#define I855_HPLLCC 0xc0
714-#define I855_CLOCK_CONTROL_MASK (3 << 0)
715-#define I855_CLOCK_133_200 (0 << 0)
716-#define I855_CLOCK_100_200 (1 << 0)
717-#define I855_CLOCK_100_133 (2 << 0)
718-#define I855_CLOCK_166_250 (3 << 0)
719-
720-/* p317, 319
721+ * The area from dword 0x10 to 0x3ff is available for driver usage.
722 */
723-#define VCLK2_VCO_M 0x6008 /* treat as 16 bit? (includes msbs) */
724-#define VCLK2_VCO_N 0x600a
725-#define VCLK2_VCO_DIV_SEL 0x6012
726-
727-#define VCLK_DIVISOR_VGA0 0x6000
728-#define VCLK_DIVISOR_VGA1 0x6004
729-#define VCLK_POST_DIV 0x6010
730-/** Selects a post divisor of 4 instead of 2. */
731-# define VGA1_PD_P2_DIV_4 (1 << 15)
732-/** Overrides the p2 post divisor field */
733-# define VGA1_PD_P1_DIV_2 (1 << 13)
734-# define VGA1_PD_P1_SHIFT 8
735-/** P1 value is 2 greater than this field */
736-# define VGA1_PD_P1_MASK (0x1f << 8)
737-/** Selects a post divisor of 4 instead of 2. */
738-# define VGA0_PD_P2_DIV_4 (1 << 7)
739-/** Overrides the p2 post divisor field */
740-# define VGA0_PD_P1_DIV_2 (1 << 5)
741-# define VGA0_PD_P1_SHIFT 0
742-/** P1 value is 2 greater than this field */
743-# define VGA0_PD_P1_MASK (0x1f << 0)
744-
745-/* PCI D state control register */
746-#define D_STATE 0x6104
747-#define DSPCLK_GATE_D 0x6200
748-
749-/* I830 CRTC registers */
750-#define HTOTAL_A 0x60000
751-#define HBLANK_A 0x60004
752-#define HSYNC_A 0x60008
753-#define VTOTAL_A 0x6000c
754-#define VBLANK_A 0x60010
755-#define VSYNC_A 0x60014
756-#define PIPEASRC 0x6001c
757-#define BCLRPAT_A 0x60020
758-#define VSYNCSHIFT_A 0x60028
759-
760-#define HTOTAL_B 0x61000
761-#define HBLANK_B 0x61004
762-#define HSYNC_B 0x61008
763-#define VTOTAL_B 0x6100c
764-#define VBLANK_B 0x61010
765-#define VSYNC_B 0x61014
766-#define PIPEBSRC 0x6101c
767-#define BCLRPAT_B 0x61020
768-#define VSYNCSHIFT_B 0x61028
769-
770-#define PP_STATUS 0x61200
771-# define PP_ON (1 << 31)
772-/**
773- * Indicates that all dependencies of the panel are on:
774- *
775- * - PLL enabled
776- * - pipe enabled
777- * - LVDS/DVOB/DVOC on
778- */
779-# define PP_READY (1 << 30)
780-# define PP_SEQUENCE_NONE (0 << 28)
781-# define PP_SEQUENCE_ON (1 << 28)
782-# define PP_SEQUENCE_OFF (2 << 28)
783-# define PP_SEQUENCE_MASK 0x30000000
784-#define PP_CONTROL 0x61204
785-# define POWER_TARGET_ON (1 << 0)
786-
787-#define LVDSPP_ON 0x61208
788-#define LVDSPP_OFF 0x6120c
789-#define PP_CYCLE 0x61210
790-
791-#define PFIT_CONTROL 0x61230
792-# define PFIT_ENABLE (1 << 31)
793-# define PFIT_PIPE_MASK (3 << 29)
794-# define PFIT_PIPE_SHIFT 29
795-# define VERT_INTERP_DISABLE (0 << 10)
796-# define VERT_INTERP_BILINEAR (1 << 10)
797-# define VERT_INTERP_MASK (3 << 10)
798-# define VERT_AUTO_SCALE (1 << 9)
799-# define HORIZ_INTERP_DISABLE (0 << 6)
800-# define HORIZ_INTERP_BILINEAR (1 << 6)
801-# define HORIZ_INTERP_MASK (3 << 6)
802-# define HORIZ_AUTO_SCALE (1 << 5)
803-# define PANEL_8TO6_DITHER_ENABLE (1 << 3)
804-
805-#define PFIT_PGM_RATIOS 0x61234
806-# define PFIT_VERT_SCALE_MASK 0xfff00000
807-# define PFIT_HORIZ_SCALE_MASK 0x0000fff0
808-
809-#define PFIT_AUTO_RATIOS 0x61238
810-
811-
812-#define DPLL_A 0x06014
813-#define DPLL_B 0x06018
814-# define DPLL_VCO_ENABLE (1 << 31)
815-# define DPLL_DVO_HIGH_SPEED (1 << 30)
816-# define DPLL_SYNCLOCK_ENABLE (1 << 29)
817-# define DPLL_VGA_MODE_DIS (1 << 28)
818-# define DPLLB_MODE_DAC_SERIAL (1 << 26) /* i915 */
819-# define DPLLB_MODE_LVDS (2 << 26) /* i915 */
820-# define DPLL_MODE_MASK (3 << 26)
821-# define DPLL_DAC_SERIAL_P2_CLOCK_DIV_10 (0 << 24) /* i915 */
822-# define DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 (1 << 24) /* i915 */
823-# define DPLLB_LVDS_P2_CLOCK_DIV_14 (0 << 24) /* i915 */
824-# define DPLLB_LVDS_P2_CLOCK_DIV_7 (1 << 24) /* i915 */
825-# define DPLL_P2_CLOCK_DIV_MASK 0x03000000 /* i915 */
826-# define DPLL_FPA01_P1_POST_DIV_MASK 0x00ff0000 /* i915 */
827-/**
828- * The i830 generation, in DAC/serial mode, defines p1 as two plus this
829- * bitfield, or just 2 if PLL_P1_DIVIDE_BY_TWO is set.
830- */
831-# define DPLL_FPA01_P1_POST_DIV_MASK_I830 0x001f0000
832-/**
833- * The i830 generation, in LVDS mode, defines P1 as the bit number set within
834- * this field (only one bit may be set).
835- */
836-# define DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS 0x003f0000
837-# define DPLL_FPA01_P1_POST_DIV_SHIFT 16
838-# define PLL_P2_DIVIDE_BY_4 (1 << 23) /* i830, required in DVO non-gang */
839-# define PLL_P1_DIVIDE_BY_TWO (1 << 21) /* i830 */
840-# define PLL_REF_INPUT_DREFCLK (0 << 13)
841-# define PLL_REF_INPUT_TVCLKINA (1 << 13) /* i830 */
842-# define PLL_REF_INPUT_TVCLKINBC (2 << 13) /* SDVO TVCLKIN */
843-# define PLLB_REF_INPUT_SPREADSPECTRUMIN (3 << 13)
844-# define PLL_REF_INPUT_MASK (3 << 13)
845-# define PLL_LOAD_PULSE_PHASE_SHIFT 9
846-/*
847- * Parallel to Serial Load Pulse phase selection.
848- * Selects the phase for the 10X DPLL clock for the PCIe
849- * digital display port. The range is 4 to 13; 10 or more
850- * is just a flip delay. The default is 6
851- */
852-# define PLL_LOAD_PULSE_PHASE_MASK (0xf << PLL_LOAD_PULSE_PHASE_SHIFT)
853-# define DISPLAY_RATE_SELECT_FPA1 (1 << 8)
854-
855-/**
856- * SDVO multiplier for 945G/GM. Not used on 965.
857- *
858- * \sa DPLL_MD_UDI_MULTIPLIER_MASK
859- */
860-# define SDVO_MULTIPLIER_MASK 0x000000ff
861-# define SDVO_MULTIPLIER_SHIFT_HIRES 4
862-# define SDVO_MULTIPLIER_SHIFT_VGA 0
863-
864-/** @defgroup DPLL_MD
865- * @{
866- */
867-/** Pipe A SDVO/UDI clock multiplier/divider register for G965. */
868-#define DPLL_A_MD 0x0601c
869-/** Pipe B SDVO/UDI clock multiplier/divider register for G965. */
870-#define DPLL_B_MD 0x06020
871-/**
872- * UDI pixel divider, controlling how many pixels are stuffed into a packet.
873- *
874- * Value is pixels minus 1. Must be set to 1 pixel for SDVO.
875- */
876-# define DPLL_MD_UDI_DIVIDER_MASK 0x3f000000
877-# define DPLL_MD_UDI_DIVIDER_SHIFT 24
878-/** UDI pixel divider for VGA, same as DPLL_MD_UDI_DIVIDER_MASK. */
879-# define DPLL_MD_VGA_UDI_DIVIDER_MASK 0x003f0000
880-# define DPLL_MD_VGA_UDI_DIVIDER_SHIFT 16
881-/**
882- * SDVO/UDI pixel multiplier.
883- *
884- * SDVO requires that the bus clock rate be between 1 and 2 Ghz, and the bus
885- * clock rate is 10 times the DPLL clock. At low resolution/refresh rate
886- * modes, the bus rate would be below the limits, so SDVO allows for stuffing
887- * dummy bytes in the datastream at an increased clock rate, with both sides of
888- * the link knowing how many bytes are fill.
889- *
890- * So, for a mode with a dotclock of 65Mhz, we would want to double the clock
891- * rate to 130Mhz to get a bus rate of 1.30Ghz. The DPLL clock rate would be
892- * set to 130Mhz, and the SDVO multiplier set to 2x in this register and
893- * through an SDVO command.
894- *
895- * This register field has values of multiplication factor minus 1, with
896- * a maximum multiplier of 5 for SDVO.
897- */
898-# define DPLL_MD_UDI_MULTIPLIER_MASK 0x00003f00
899-# define DPLL_MD_UDI_MULTIPLIER_SHIFT 8
900-/** SDVO/UDI pixel multiplier for VGA, same as DPLL_MD_UDI_MULTIPLIER_MASK.
901- * This best be set to the default value (3) or the CRT won't work. No,
902- * I don't entirely understand what this does...
903- */
904-# define DPLL_MD_VGA_UDI_MULTIPLIER_MASK 0x0000003f
905-# define DPLL_MD_VGA_UDI_MULTIPLIER_SHIFT 0
906-/** @} */
907-
908-#define DPLL_TEST 0x606c
909-# define DPLLB_TEST_SDVO_DIV_1 (0 << 22)
910-# define DPLLB_TEST_SDVO_DIV_2 (1 << 22)
911-# define DPLLB_TEST_SDVO_DIV_4 (2 << 22)
912-# define DPLLB_TEST_SDVO_DIV_MASK (3 << 22)
913-# define DPLLB_TEST_N_BYPASS (1 << 19)
914-# define DPLLB_TEST_M_BYPASS (1 << 18)
915-# define DPLLB_INPUT_BUFFER_ENABLE (1 << 16)
916-# define DPLLA_TEST_N_BYPASS (1 << 3)
917-# define DPLLA_TEST_M_BYPASS (1 << 2)
918-# define DPLLA_INPUT_BUFFER_ENABLE (1 << 0)
919-
920-#define ADPA 0x61100
921-#define ADPA_DAC_ENABLE (1<<31)
922-#define ADPA_DAC_DISABLE 0
923-#define ADPA_PIPE_SELECT_MASK (1<<30)
924-#define ADPA_PIPE_A_SELECT 0
925-#define ADPA_PIPE_B_SELECT (1<<30)
926-#define ADPA_USE_VGA_HVPOLARITY (1<<15)
927-#define ADPA_SETS_HVPOLARITY 0
928-#define ADPA_VSYNC_CNTL_DISABLE (1<<11)
929-#define ADPA_VSYNC_CNTL_ENABLE 0
930-#define ADPA_HSYNC_CNTL_DISABLE (1<<10)
931-#define ADPA_HSYNC_CNTL_ENABLE 0
932-#define ADPA_VSYNC_ACTIVE_HIGH (1<<4)
933-#define ADPA_VSYNC_ACTIVE_LOW 0
934-#define ADPA_HSYNC_ACTIVE_HIGH (1<<3)
935-#define ADPA_HSYNC_ACTIVE_LOW 0
936-
937-#define FPA0 0x06040
938-#define FPA1 0x06044
939-#define FPB0 0x06048
940-#define FPB1 0x0604c
941-# define FP_N_DIV_MASK 0x003f0000
942-# define FP_N_DIV_SHIFT 16
943-# define FP_M1_DIV_MASK 0x00003f00
944-# define FP_M1_DIV_SHIFT 8
945-# define FP_M2_DIV_MASK 0x0000003f
946-# define FP_M2_DIV_SHIFT 0
947-
948-
949-#define PORT_HOTPLUG_EN 0x61110
950-# define SDVOB_HOTPLUG_INT_EN (1 << 26)
951-# define SDVOC_HOTPLUG_INT_EN (1 << 25)
952-# define TV_HOTPLUG_INT_EN (1 << 18)
953-# define CRT_HOTPLUG_INT_EN (1 << 9)
954-# define CRT_HOTPLUG_FORCE_DETECT (1 << 3)
955-
956-#define PORT_HOTPLUG_STAT 0x61114
957-# define CRT_HOTPLUG_INT_STATUS (1 << 11)
958-# define TV_HOTPLUG_INT_STATUS (1 << 10)
959-# define CRT_HOTPLUG_MONITOR_MASK (3 << 8)
960-# define CRT_HOTPLUG_MONITOR_COLOR (3 << 8)
961-# define CRT_HOTPLUG_MONITOR_MONO (2 << 8)
962-# define CRT_HOTPLUG_MONITOR_NONE (0 << 8)
963-# define SDVOC_HOTPLUG_INT_STATUS (1 << 7)
964-# define SDVOB_HOTPLUG_INT_STATUS (1 << 6)
965-
966-#define SDVOB 0x61140
967-#define SDVOC 0x61160
968-#define SDVO_ENABLE (1 << 31)
969-#define SDVO_PIPE_B_SELECT (1 << 30)
970-#define SDVO_STALL_SELECT (1 << 29)
971-#define SDVO_INTERRUPT_ENABLE (1 << 26)
972-/**
973- * 915G/GM SDVO pixel multiplier.
974- *
975- * Programmed value is multiplier - 1, up to 5x.
976- *
977- * \sa DPLL_MD_UDI_MULTIPLIER_MASK
978- */
979-#define SDVO_PORT_MULTIPLY_MASK (7 << 23)
980-#define SDVO_PORT_MULTIPLY_SHIFT 23
981-#define SDVO_PHASE_SELECT_MASK (15 << 19)
982-#define SDVO_PHASE_SELECT_DEFAULT (6 << 19)
983-#define SDVO_CLOCK_OUTPUT_INVERT (1 << 18)
984-#define SDVOC_GANG_MODE (1 << 16)
985-#define SDVO_BORDER_ENABLE (1 << 7)
986-#define SDVOB_PCIE_CONCURRENCY (1 << 3)
987-#define SDVO_DETECTED (1 << 2)
988-/* Bits to be preserved when writing */
989-#define SDVOB_PRESERVE_MASK ((1 << 17) | (1 << 16) | (1 << 14))
990-#define SDVOC_PRESERVE_MASK (1 << 17)
991-
992-/** @defgroup LVDS
993- * @{
994- */
995-/**
996- * This register controls the LVDS output enable, pipe selection, and data
997- * format selection.
998- *
999- * All of the clock/data pairs are force powered down by power sequencing.
1000- */
1001-#define LVDS 0x61180
1002-/**
1003- * Enables the LVDS port. This bit must be set before DPLLs are enabled, as
1004- * the DPLL semantics change when the LVDS is assigned to that pipe.
1005- */
1006-# define LVDS_PORT_EN (1 << 31)
1007-/** Selects pipe B for LVDS data. Must be set on pre-965. */
1008-# define LVDS_PIPEB_SELECT (1 << 30)
1009-
1010-/**
1011- * Enables the A0-A2 data pairs and CLKA, containing 18 bits of color data per
1012- * pixel.
1013- */
1014-# define LVDS_A0A2_CLKA_POWER_MASK (3 << 8)
1015-# define LVDS_A0A2_CLKA_POWER_DOWN (0 << 8)
1016-# define LVDS_A0A2_CLKA_POWER_UP (3 << 8)
1017-/**
1018- * Controls the A3 data pair, which contains the additional LSBs for 24 bit
1019- * mode. Only enabled if LVDS_A0A2_CLKA_POWER_UP also indicates it should be
1020- * on.
1021- */
1022-# define LVDS_A3_POWER_MASK (3 << 6)
1023-# define LVDS_A3_POWER_DOWN (0 << 6)
1024-# define LVDS_A3_POWER_UP (3 << 6)
1025-/**
1026- * Controls the CLKB pair. This should only be set when LVDS_B0B3_POWER_UP
1027- * is set.
1028- */
1029-# define LVDS_CLKB_POWER_MASK (3 << 4)
1030-# define LVDS_CLKB_POWER_DOWN (0 << 4)
1031-# define LVDS_CLKB_POWER_UP (3 << 4)
1032-
1033-/**
1034- * Controls the B0-B3 data pairs. This must be set to match the DPLL p2
1035- * setting for whether we are in dual-channel mode. The B3 pair will
1036- * additionally only be powered up when LVDS_A3_POWER_UP is set.
1037- */
1038-# define LVDS_B0B3_POWER_MASK (3 << 2)
1039-# define LVDS_B0B3_POWER_DOWN (0 << 2)
1040-# define LVDS_B0B3_POWER_UP (3 << 2)
1041-
1042-#define PIPEACONF 0x70008
1043-#define PIPEACONF_ENABLE (1<<31)
1044-#define PIPEACONF_DISABLE 0
1045-#define PIPEACONF_DOUBLE_WIDE (1<<30)
1046-#define I965_PIPECONF_ACTIVE (1<<30)
1047-#define PIPEACONF_SINGLE_WIDE 0
1048-#define PIPEACONF_PIPE_UNLOCKED 0
1049-#define PIPEACONF_PIPE_LOCKED (1<<25)
1050-#define PIPEACONF_PALETTE 0
1051-#define PIPEACONF_GAMMA (1<<24)
1052-#define PIPECONF_FORCE_BORDER (1<<25)
1053-#define PIPECONF_PROGRESSIVE (0 << 21)
1054-#define PIPECONF_INTERLACE_W_FIELD_INDICATION (6 << 21)
1055-#define PIPECONF_INTERLACE_FIELD_0_ONLY (7 << 21)
1056-
1057-#define DSPARB 0x70030
1058-#define DSPARB_CSTART_MASK (0x7f << 7)
1059-#define DSPARB_CSTART_SHIFT 7
1060-#define DSPARB_BSTART_MASK (0x7f)
1061-#define DSPARB_BSTART_SHIFT 0
1062-
1063-#define PIPEBCONF 0x71008
1064-#define PIPEBCONF_ENABLE (1<<31)
1065-#define PIPEBCONF_DISABLE 0
1066-#define PIPEBCONF_DOUBLE_WIDE (1<<30)
1067-#define PIPEBCONF_DISABLE 0
1068-#define PIPEBCONF_GAMMA (1<<24)
1069-#define PIPEBCONF_PALETTE 0
1070-
1071-#define PIPEBGCMAXRED 0x71010
1072-#define PIPEBGCMAXGREEN 0x71014
1073-#define PIPEBGCMAXBLUE 0x71018
1074-#define PIPEBSTAT 0x71024
1075-#define PIPEBFRAMEHIGH 0x71040
1076-#define PIPEBFRAMEPIXEL 0x71044
1077-
1078-#define DSPACNTR 0x70180
1079-#define DSPBCNTR 0x71180
1080-#define DISPLAY_PLANE_ENABLE (1<<31)
1081-#define DISPLAY_PLANE_DISABLE 0
1082-#define DISPPLANE_GAMMA_ENABLE (1<<30)
1083-#define DISPPLANE_GAMMA_DISABLE 0
1084-#define DISPPLANE_PIXFORMAT_MASK (0xf<<26)
1085-#define DISPPLANE_8BPP (0x2<<26)
1086-#define DISPPLANE_15_16BPP (0x4<<26)
1087-#define DISPPLANE_16BPP (0x5<<26)
1088-#define DISPPLANE_32BPP_NO_ALPHA (0x6<<26)
1089-#define DISPPLANE_32BPP (0x7<<26)
1090-#define DISPPLANE_STEREO_ENABLE (1<<25)
1091-#define DISPPLANE_STEREO_DISABLE 0
1092-#define DISPPLANE_SEL_PIPE_MASK (1<<24)
1093-#define DISPPLANE_SEL_PIPE_A 0
1094-#define DISPPLANE_SEL_PIPE_B (1<<24)
1095-#define DISPPLANE_SRC_KEY_ENABLE (1<<22)
1096-#define DISPPLANE_SRC_KEY_DISABLE 0
1097-#define DISPPLANE_LINE_DOUBLE (1<<20)
1098-#define DISPPLANE_NO_LINE_DOUBLE 0
1099-#define DISPPLANE_STEREO_POLARITY_FIRST 0
1100-#define DISPPLANE_STEREO_POLARITY_SECOND (1<<18)
1101-/* plane B only */
1102-#define DISPPLANE_ALPHA_TRANS_ENABLE (1<<15)
1103-#define DISPPLANE_ALPHA_TRANS_DISABLE 0
1104-#define DISPPLANE_SPRITE_ABOVE_DISPLAYA 0
1105-#define DISPPLANE_SPRITE_ABOVE_OVERLAY (1)
1106-
1107-#define DSPABASE 0x70184
1108-#define DSPASTRIDE 0x70188
1109-
1110-#define DSPBBASE 0x71184
1111-#define DSPBADDR DSPBBASE
1112-#define DSPBSTRIDE 0x71188
1113-
1114-#define DSPAKEYVAL 0x70194
1115-#define DSPAKEYMASK 0x70198
1116-
1117-#define DSPAPOS 0x7018C /* reserved */
1118-#define DSPASIZE 0x70190
1119-#define DSPBPOS 0x7118C
1120-#define DSPBSIZE 0x71190
1121-
1122-#define DSPASURF 0x7019C
1123-#define DSPATILEOFF 0x701A4
1124-
1125-#define DSPBSURF 0x7119C
1126-#define DSPBTILEOFF 0x711A4
1127-
1128-#define VGACNTRL 0x71400
1129-# define VGA_DISP_DISABLE (1 << 31)
1130-# define VGA_2X_MODE (1 << 30)
1131-# define VGA_PIPE_B_SELECT (1 << 29)
1132-
1133-/*
1134- * Some BIOS scratch area registers. The 845 (and 830?) store the amount
1135- * of video memory available to the BIOS in SWF1.
1136- */
1137-
1138-#define SWF0 0x71410
1139-
1140-/*
1141- * 855 scratch registers.
1142- */
1143-#define SWF10 0x70410
1144-
1145-#define SWF30 0x72414
1146-
1147-/*
1148- * Overlay registers. These are overlay registers accessed via MMIO.
1149- * Those loaded via the overlay register page are defined in i830_video.c.
1150- */
1151-#define OVADD 0x30000
1152-
1153-#define DOVSTA 0x30008
1154-#define OC_BUF (0x3<<20)
1155+#define READ_HWSP(dev_priv, reg) (((volatile u32*)(dev_priv->hw_status_page))[reg])
1156+#define READ_BREADCRUMB(dev_priv) READ_HWSP(dev_priv, 5)
1157
1158-#define OGAMC5 0x30010
1159-#define OGAMC4 0x30014
1160-#define OGAMC3 0x30018
1161-#define OGAMC2 0x3001c
1162-#define OGAMC1 0x30020
1163-#define OGAMC0 0x30024
1164-/*
1165- * Palette registers
1166- */
1167-#define PALETTE_A 0x0a000
1168-#define PALETTE_B 0x0a800
1169+extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
1170
1171 #define IS_I830(dev) ((dev)->pci_device == 0x3577)
1172 #define IS_845G(dev) ((dev)->pci_device == 0x2562)
1173diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
1174index df03611..4a2de78 100644
1175--- a/drivers/gpu/drm/i915/i915_irq.c
1176+++ b/drivers/gpu/drm/i915/i915_irq.c
1177@@ -31,10 +31,6 @@
1178 #include "i915_drm.h"
1179 #include "i915_drv.h"
1180
1181-#define USER_INT_FLAG (1<<1)
1182-#define VSYNC_PIPEB_FLAG (1<<5)
1183-#define VSYNC_PIPEA_FLAG (1<<7)
1184-
1185 #define MAX_NOPID ((u32)~0)
1186
1187 /**
1188@@ -236,40 +232,43 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
1189 u16 temp;
1190 u32 pipea_stats, pipeb_stats;
1191
1192- pipea_stats = I915_READ(I915REG_PIPEASTAT);
1193- pipeb_stats = I915_READ(I915REG_PIPEBSTAT);
1194+ pipea_stats = I915_READ(PIPEASTAT);
1195+ pipeb_stats = I915_READ(PIPEBSTAT);
1196
1197- temp = I915_READ16(I915REG_INT_IDENTITY_R);
1198+ temp = I915_READ16(IIR);
1199
1200- temp &= (USER_INT_FLAG | VSYNC_PIPEA_FLAG | VSYNC_PIPEB_FLAG);
1201+ temp &= (I915_USER_INTERRUPT |
1202+ I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT |
1203+ I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT);
1204
1205 DRM_DEBUG("%s flag=%08x\n", __FUNCTION__, temp);
1206
1207 if (temp == 0)
1208 return IRQ_NONE;
1209
1210- I915_WRITE16(I915REG_INT_IDENTITY_R, temp);
1211- (void) I915_READ16(I915REG_INT_IDENTITY_R);
1212+ I915_WRITE16(IIR, temp);
1213+ (void) I915_READ16(IIR);
1214 DRM_READMEMORYBARRIER();
1215
1216 dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
1217
1218- if (temp & USER_INT_FLAG)
1219+ if (temp & I915_USER_INTERRUPT)
1220 DRM_WAKEUP(&dev_priv->irq_queue);
1221
1222- if (temp & (VSYNC_PIPEA_FLAG | VSYNC_PIPEB_FLAG)) {
1223+ if (temp & (I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT |
1224+ I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT)) {
1225 int vblank_pipe = dev_priv->vblank_pipe;
1226
1227 if ((vblank_pipe &
1228 (DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B))
1229 == (DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B)) {
1230- if (temp & VSYNC_PIPEA_FLAG)
1231+ if (temp & I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT)
1232 atomic_inc(&dev->vbl_received);
1233- if (temp & VSYNC_PIPEB_FLAG)
1234+ if (temp & I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT)
1235 atomic_inc(&dev->vbl_received2);
1236- } else if (((temp & VSYNC_PIPEA_FLAG) &&
1237+ } else if (((temp & I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT) &&
1238 (vblank_pipe & DRM_I915_VBLANK_PIPE_A)) ||
1239- ((temp & VSYNC_PIPEB_FLAG) &&
1240+ ((temp & I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT) &&
1241 (vblank_pipe & DRM_I915_VBLANK_PIPE_B)))
1242 atomic_inc(&dev->vbl_received);
1243
1244@@ -278,12 +277,12 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
1245
1246 if (dev_priv->swaps_pending > 0)
1247 drm_locked_tasklet(dev, i915_vblank_tasklet);
1248- I915_WRITE(I915REG_PIPEASTAT,
1249+ I915_WRITE(PIPEASTAT,
1250 pipea_stats|I915_VBLANK_INTERRUPT_ENABLE|
1251- I915_VBLANK_CLEAR);
1252- I915_WRITE(I915REG_PIPEBSTAT,
1253+ PIPE_VBLANK_INTERRUPT_STATUS);
1254+ I915_WRITE(PIPEBSTAT,
1255 pipeb_stats|I915_VBLANK_INTERRUPT_ENABLE|
1256- I915_VBLANK_CLEAR);
1257+ PIPE_VBLANK_INTERRUPT_STATUS);
1258 }
1259
1260 return IRQ_HANDLED;
1261@@ -304,12 +303,12 @@ static int i915_emit_irq(struct drm_device * dev)
1262 dev_priv->sarea_priv->last_enqueue = dev_priv->counter = 1;
1263
1264 BEGIN_LP_RING(6);
1265- OUT_RING(CMD_STORE_DWORD_IDX);
1266- OUT_RING(20);
1267+ OUT_RING(MI_STORE_DWORD_INDEX);
1268+ OUT_RING(5 << MI_STORE_DWORD_INDEX_SHIFT);
1269 OUT_RING(dev_priv->counter);
1270 OUT_RING(0);
1271 OUT_RING(0);
1272- OUT_RING(GFX_OP_USER_INTERRUPT);
1273+ OUT_RING(MI_USER_INTERRUPT);
1274 ADVANCE_LP_RING();
1275
1276 return dev_priv->counter;
1277@@ -421,11 +420,11 @@ static void i915_enable_interrupt (struct drm_device *dev)
1278
1279 flag = 0;
1280 if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_A)
1281- flag |= VSYNC_PIPEA_FLAG;
1282+ flag |= I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT;
1283 if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_B)
1284- flag |= VSYNC_PIPEB_FLAG;
1285+ flag |= I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
1286
1287- I915_WRITE16(I915REG_INT_ENABLE_R, USER_INT_FLAG | flag);
1288+ I915_WRITE16(IER, I915_USER_INTERRUPT | flag);
1289 }
1290
1291 /* Set the vblank monitor pipe
1292@@ -465,11 +464,11 @@ int i915_vblank_pipe_get(struct drm_device *dev, void *data,
1293 return -EINVAL;
1294 }
1295
1296- flag = I915_READ(I915REG_INT_ENABLE_R);
1297+ flag = I915_READ(IER);
1298 pipe->pipe = 0;
1299- if (flag & VSYNC_PIPEA_FLAG)
1300+ if (flag & I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT)
1301 pipe->pipe |= DRM_I915_VBLANK_PIPE_A;
1302- if (flag & VSYNC_PIPEB_FLAG)
1303+ if (flag & I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT)
1304 pipe->pipe |= DRM_I915_VBLANK_PIPE_B;
1305
1306 return 0;
1307@@ -587,9 +586,9 @@ void i915_driver_irq_preinstall(struct drm_device * dev)
1308 {
1309 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
1310
1311- I915_WRITE16(I915REG_HWSTAM, 0xfffe);
1312- I915_WRITE16(I915REG_INT_MASK_R, 0x0);
1313- I915_WRITE16(I915REG_INT_ENABLE_R, 0x0);
1314+ I915_WRITE16(HWSTAM, 0xfffe);
1315+ I915_WRITE16(IMR, 0x0);
1316+ I915_WRITE16(IER, 0x0);
1317 }
1318
1319 void i915_driver_irq_postinstall(struct drm_device * dev)
1320@@ -614,10 +613,10 @@ void i915_driver_irq_uninstall(struct drm_device * dev)
1321 if (!dev_priv)
1322 return;
1323
1324- I915_WRITE16(I915REG_HWSTAM, 0xffff);
1325- I915_WRITE16(I915REG_INT_MASK_R, 0xffff);
1326- I915_WRITE16(I915REG_INT_ENABLE_R, 0x0);
1327+ I915_WRITE16(HWSTAM, 0xffff);
1328+ I915_WRITE16(IMR, 0xffff);
1329+ I915_WRITE16(IER, 0x0);
1330
1331- temp = I915_READ16(I915REG_INT_IDENTITY_R);
1332- I915_WRITE16(I915REG_INT_IDENTITY_R, temp);
1333+ temp = I915_READ16(IIR);
1334+ I915_WRITE16(IIR, temp);
1335 }
1336diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
1337new file mode 100644
1338index 0000000..477c64e
1339--- /dev/null
1340+++ b/drivers/gpu/drm/i915/i915_reg.h
1341@@ -0,0 +1,1405 @@
1342+/* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
1343+ * All Rights Reserved.
1344+ *
1345+ * Permission is hereby granted, free of charge, to any person obtaining a
1346+ * copy of this software and associated documentation files (the
1347+ * "Software"), to deal in the Software without restriction, including
1348+ * without limitation the rights to use, copy, modify, merge, publish,
1349+ * distribute, sub license, and/or sell copies of the Software, and to
1350+ * permit persons to whom the Software is furnished to do so, subject to
1351+ * the following conditions:
1352+ *
1353+ * The above copyright notice and this permission notice (including the
1354+ * next paragraph) shall be included in all copies or substantial portions
1355+ * of the Software.
1356+ *
1357+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
1358+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
1359+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
1360+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
1361+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
1362+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
1363+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1364+ */
1365+
1366+#ifndef _I915_REG_H_
1367+#define _I915_REG_H_
1368+
1369+/* MCH MMIO space */
1370+/** 915-945 and GM965 MCH register controlling DRAM channel access */
1371+#define DCC 0x200
1372+#define DCC_ADDRESSING_MODE_SINGLE_CHANNEL (0 << 0)
1373+#define DCC_ADDRESSING_MODE_DUAL_CHANNEL_ASYMMETRIC (1 << 0)
1374+#define DCC_ADDRESSING_MODE_DUAL_CHANNEL_INTERLEAVED (2 << 0)
1375+#define DCC_ADDRESSING_MODE_MASK (3 << 0)
1376+#define DCC_CHANNEL_XOR_DISABLE (1 << 10)
1377+
1378+/** 965 MCH register controlling DRAM channel configuration */
1379+#define CHDECMISC 0x111
1380+#define CHDECMISC_FLEXMEMORY (1 << 1)
1381+
1382+/*
1383+ * The Bridge device's PCI config space has information about the
1384+ * fb aperture size and the amount of pre-reserved memory.
1385+ */
1386+#define INTEL_GMCH_CTRL 0x52
1387+#define INTEL_GMCH_ENABLED 0x4
1388+#define INTEL_GMCH_MEM_MASK 0x1
1389+#define INTEL_GMCH_MEM_64M 0x1
1390+#define INTEL_GMCH_MEM_128M 0
1391+
1392+#define INTEL_855_GMCH_GMS_MASK (0x7 << 4)
1393+#define INTEL_855_GMCH_GMS_DISABLED (0x0 << 4)
1394+#define INTEL_855_GMCH_GMS_STOLEN_1M (0x1 << 4)
1395+#define INTEL_855_GMCH_GMS_STOLEN_4M (0x2 << 4)
1396+#define INTEL_855_GMCH_GMS_STOLEN_8M (0x3 << 4)
1397+#define INTEL_855_GMCH_GMS_STOLEN_16M (0x4 << 4)
1398+#define INTEL_855_GMCH_GMS_STOLEN_32M (0x5 << 4)
1399+
1400+#define INTEL_915G_GMCH_GMS_STOLEN_48M (0x6 << 4)
1401+#define INTEL_915G_GMCH_GMS_STOLEN_64M (0x7 << 4)
1402+
1403+/* PCI config space */
1404+
1405+#define HPLLCC 0xc0 /* 855 only */
1406+#define GC_CLOCK_CONTROL_MASK (3 << 0)
1407+#define GC_CLOCK_133_200 (0 << 0)
1408+#define GC_CLOCK_100_200 (1 << 0)
1409+#define GC_CLOCK_100_133 (2 << 0)
1410+#define GC_CLOCK_166_250 (3 << 0)
1411+#define GCFGC 0xf0 /* 915+ only */
1412+#define GC_LOW_FREQUENCY_ENABLE (1 << 7)
1413+#define GC_DISPLAY_CLOCK_190_200_MHZ (0 << 4)
1414+#define GC_DISPLAY_CLOCK_333_MHZ (4 << 4)
1415+#define GC_DISPLAY_CLOCK_MASK (7 << 4)
1416+#define LBB 0xf4
1417+
1418+/* VGA stuff */
1419+
1420+#define VGA_ST01_MDA 0x3ba
1421+#define VGA_ST01_CGA 0x3da
1422+
1423+#define VGA_MSR_WRITE 0x3c2
1424+#define VGA_MSR_READ 0x3cc
1425+#define VGA_MSR_MEM_EN (1<<1)
1426+#define VGA_MSR_CGA_MODE (1<<0)
1427+
1428+#define VGA_SR_INDEX 0x3c4
1429+#define VGA_SR_DATA 0x3c5
1430+
1431+#define VGA_AR_INDEX 0x3c0
1432+#define VGA_AR_VID_EN (1<<5)
1433+#define VGA_AR_DATA_WRITE 0x3c0
1434+#define VGA_AR_DATA_READ 0x3c1
1435+
1436+#define VGA_GR_INDEX 0x3ce
1437+#define VGA_GR_DATA 0x3cf
1438+/* GR05 */
1439+#define VGA_GR_MEM_READ_MODE_SHIFT 3
1440+#define VGA_GR_MEM_READ_MODE_PLANE 1
1441+/* GR06 */
1442+#define VGA_GR_MEM_MODE_MASK 0xc
1443+#define VGA_GR_MEM_MODE_SHIFT 2
1444+#define VGA_GR_MEM_A0000_AFFFF 0
1445+#define VGA_GR_MEM_A0000_BFFFF 1
1446+#define VGA_GR_MEM_B0000_B7FFF 2
1447+#define VGA_GR_MEM_B0000_BFFFF 3
1448+
1449+#define VGA_DACMASK 0x3c6
1450+#define VGA_DACRX 0x3c7
1451+#define VGA_DACWX 0x3c8
1452+#define VGA_DACDATA 0x3c9
1453+
1454+#define VGA_CR_INDEX_MDA 0x3b4
1455+#define VGA_CR_DATA_MDA 0x3b5
1456+#define VGA_CR_INDEX_CGA 0x3d4
1457+#define VGA_CR_DATA_CGA 0x3d5
1458+
1459+/*
1460+ * Memory interface instructions used by the kernel
1461+ */
1462+#define MI_INSTR(opcode, flags) (((opcode) << 23) | (flags))
1463+
1464+#define MI_NOOP MI_INSTR(0, 0)
1465+#define MI_USER_INTERRUPT MI_INSTR(0x02, 0)
1466+#define MI_WAIT_FOR_EVENT MI_INSTR(0x03, 0)
1467+#define MI_WAIT_FOR_PLANE_B_FLIP (1<<6)
1468+#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2)
1469+#define MI_WAIT_FOR_PLANE_A_SCANLINES (1<<1)
1470+#define MI_FLUSH MI_INSTR(0x04, 0)
1471+#define MI_READ_FLUSH (1 << 0)
1472+#define MI_EXE_FLUSH (1 << 1)
1473+#define MI_NO_WRITE_FLUSH (1 << 2)
1474+#define MI_SCENE_COUNT (1 << 3) /* just increment scene count */
1475+#define MI_END_SCENE (1 << 4) /* flush binner and incr scene count */
1476+#define MI_BATCH_BUFFER_END MI_INSTR(0x0a, 0)
1477+#define MI_REPORT_HEAD MI_INSTR(0x07, 0)
1478+#define MI_LOAD_SCAN_LINES_INCL MI_INSTR(0x12, 0)
1479+#define MI_STORE_DWORD_IMM MI_INSTR(0x20, 1)
1480+#define MI_MEM_VIRTUAL (1 << 22) /* 965+ only */
1481+#define MI_STORE_DWORD_INDEX MI_INSTR(0x21, 1)
1482+#define MI_STORE_DWORD_INDEX_SHIFT 2
1483+#define MI_LOAD_REGISTER_IMM MI_INSTR(0x22, 1)
1484+#define MI_BATCH_BUFFER MI_INSTR(0x30, 1)
1485+#define MI_BATCH_NON_SECURE (1)
1486+#define MI_BATCH_NON_SECURE_I965 (1<<8)
1487+#define MI_BATCH_BUFFER_START MI_INSTR(0x31, 0)
1488+
1489+/*
1490+ * 3D instructions used by the kernel
1491+ */
1492+#define GFX_INSTR(opcode, flags) ((0x3 << 29) | ((opcode) << 24) | (flags))
1493+
1494+#define GFX_OP_RASTER_RULES ((0x3<<29)|(0x7<<24))
1495+#define GFX_OP_SCISSOR ((0x3<<29)|(0x1c<<24)|(0x10<<19))
1496+#define SC_UPDATE_SCISSOR (0x1<<1)
1497+#define SC_ENABLE_MASK (0x1<<0)
1498+#define SC_ENABLE (0x1<<0)
1499+#define GFX_OP_LOAD_INDIRECT ((0x3<<29)|(0x1d<<24)|(0x7<<16))
1500+#define GFX_OP_SCISSOR_INFO ((0x3<<29)|(0x1d<<24)|(0x81<<16)|(0x1))
1501+#define SCI_YMIN_MASK (0xffff<<16)
1502+#define SCI_XMIN_MASK (0xffff<<0)
1503+#define SCI_YMAX_MASK (0xffff<<16)
1504+#define SCI_XMAX_MASK (0xffff<<0)
1505+#define GFX_OP_SCISSOR_ENABLE ((0x3<<29)|(0x1c<<24)|(0x10<<19))
1506+#define GFX_OP_SCISSOR_RECT ((0x3<<29)|(0x1d<<24)|(0x81<<16)|1)
1507+#define GFX_OP_COLOR_FACTOR ((0x3<<29)|(0x1d<<24)|(0x1<<16)|0x0)
1508+#define GFX_OP_STIPPLE ((0x3<<29)|(0x1d<<24)|(0x83<<16))
1509+#define GFX_OP_MAP_INFO ((0x3<<29)|(0x1d<<24)|0x4)
1510+#define GFX_OP_DESTBUFFER_VARS ((0x3<<29)|(0x1d<<24)|(0x85<<16)|0x0)
1511+#define GFX_OP_DESTBUFFER_INFO ((0x3<<29)|(0x1d<<24)|(0x8e<<16)|1)
1512+#define GFX_OP_DRAWRECT_INFO ((0x3<<29)|(0x1d<<24)|(0x80<<16)|(0x3))
1513+#define GFX_OP_DRAWRECT_INFO_I965 ((0x7900<<16)|0x2)
1514+#define SRC_COPY_BLT_CMD ((2<<29)|(0x43<<22)|4)
1515+#define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6)
1516+#define XY_MONO_SRC_COPY_IMM_BLT ((2<<29)|(0x71<<22)|5)
1517+#define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21)
1518+#define XY_SRC_COPY_BLT_WRITE_RGB (1<<20)
1519+#define BLT_DEPTH_8 (0<<24)
1520+#define BLT_DEPTH_16_565 (1<<24)
1521+#define BLT_DEPTH_16_1555 (2<<24)
1522+#define BLT_DEPTH_32 (3<<24)
1523+#define BLT_ROP_GXCOPY (0xcc<<16)
1524+#define XY_SRC_COPY_BLT_SRC_TILED (1<<15) /* 965+ only */
1525+#define XY_SRC_COPY_BLT_DST_TILED (1<<11) /* 965+ only */
1526+#define CMD_OP_DISPLAYBUFFER_INFO ((0x0<<29)|(0x14<<23)|2)
1527+#define ASYNC_FLIP (1<<22)
1528+#define DISPLAY_PLANE_A (0<<20)
1529+#define DISPLAY_PLANE_B (1<<20)
1530+
1531+/*
1532+ * Instruction and interrupt control regs
1533+ */
1534+
1535+#define PRB0_TAIL 0x02030
1536+#define PRB0_HEAD 0x02034
1537+#define PRB0_START 0x02038
1538+#define PRB0_CTL 0x0203c
1539+#define TAIL_ADDR 0x001FFFF8
1540+#define HEAD_WRAP_COUNT 0xFFE00000
1541+#define HEAD_WRAP_ONE 0x00200000
1542+#define HEAD_ADDR 0x001FFFFC
1543+#define RING_NR_PAGES 0x001FF000
1544+#define RING_REPORT_MASK 0x00000006
1545+#define RING_REPORT_64K 0x00000002
1546+#define RING_REPORT_128K 0x00000004
1547+#define RING_NO_REPORT 0x00000000
1548+#define RING_VALID_MASK 0x00000001
1549+#define RING_VALID 0x00000001
1550+#define RING_INVALID 0x00000000
1551+#define PRB1_TAIL 0x02040 /* 915+ only */
1552+#define PRB1_HEAD 0x02044 /* 915+ only */
1553+#define PRB1_START 0x02048 /* 915+ only */
1554+#define PRB1_CTL 0x0204c /* 915+ only */
1555+#define ACTHD_I965 0x02074
1556+#define HWS_PGA 0x02080
1557+#define HWS_ADDRESS_MASK 0xfffff000
1558+#define HWS_START_ADDRESS_SHIFT 4
1559+#define IPEIR 0x02088
1560+#define NOPID 0x02094
1561+#define HWSTAM 0x02098
1562+#define SCPD0 0x0209c /* 915+ only */
1563+#define IER 0x020a0
1564+#define IIR 0x020a4
1565+#define IMR 0x020a8
1566+#define ISR 0x020ac
1567+#define I915_PIPE_CONTROL_NOTIFY_INTERRUPT (1<<18)
1568+#define I915_DISPLAY_PORT_INTERRUPT (1<<17)
1569+#define I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT (1<<15)
1570+#define I915_GMCH_THERMAL_SENSOR_EVENT_INTERRUPT (1<<14)
1571+#define I915_HWB_OOM_INTERRUPT (1<<13)
1572+#define I915_SYNC_STATUS_INTERRUPT (1<<12)
1573+#define I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT (1<<11)
1574+#define I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT (1<<10)
1575+#define I915_OVERLAY_PLANE_FLIP_PENDING_INTERRUPT (1<<9)
1576+#define I915_DISPLAY_PLANE_C_FLIP_PENDING_INTERRUPT (1<<8)
1577+#define I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT (1<<7)
1578+#define I915_DISPLAY_PIPE_A_EVENT_INTERRUPT (1<<6)
1579+#define I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT (1<<5)
1580+#define I915_DISPLAY_PIPE_B_EVENT_INTERRUPT (1<<4)
1581+#define I915_DEBUG_INTERRUPT (1<<2)
1582+#define I915_USER_INTERRUPT (1<<1)
1583+#define I915_ASLE_INTERRUPT (1<<0)
1584+#define EIR 0x020b0
1585+#define EMR 0x020b4
1586+#define ESR 0x020b8
1587+#define INSTPM 0x020c0
1588+#define ACTHD 0x020c8
1589+#define FW_BLC 0x020d8
1590+#define FW_BLC_SELF 0x020e0 /* 915+ only */
1591+#define MI_ARB_STATE 0x020e4 /* 915+ only */
1592+#define CACHE_MODE_0 0x02120 /* 915+ only */
1593+#define CM0_MASK_SHIFT 16
1594+#define CM0_IZ_OPT_DISABLE (1<<6)
1595+#define CM0_ZR_OPT_DISABLE (1<<5)
1596+#define CM0_DEPTH_EVICT_DISABLE (1<<4)
1597+#define CM0_COLOR_EVICT_DISABLE (1<<3)
1598+#define CM0_DEPTH_WRITE_DISABLE (1<<1)
1599+#define CM0_RC_OP_FLUSH_DISABLE (1<<0)
1600+#define GFX_FLSH_CNTL 0x02170 /* 915+ only */
1601+
1602+/*
1603+ * Framebuffer compression (915+ only)
1604+ */
1605+
1606+#define FBC_CFB_BASE 0x03200 /* 4k page aligned */
1607+#define FBC_LL_BASE 0x03204 /* 4k page aligned */
1608+#define FBC_CONTROL 0x03208
1609+#define FBC_CTL_EN (1<<31)
1610+#define FBC_CTL_PERIODIC (1<<30)
1611+#define FBC_CTL_INTERVAL_SHIFT (16)
1612+#define FBC_CTL_UNCOMPRESSIBLE (1<<14)
1613+#define FBC_CTL_STRIDE_SHIFT (5)
1614+#define FBC_CTL_FENCENO (1<<0)
1615+#define FBC_COMMAND 0x0320c
1616+#define FBC_CMD_COMPRESS (1<<0)
1617+#define FBC_STATUS 0x03210
1618+#define FBC_STAT_COMPRESSING (1<<31)
1619+#define FBC_STAT_COMPRESSED (1<<30)
1620+#define FBC_STAT_MODIFIED (1<<29)
1621+#define FBC_STAT_CURRENT_LINE (1<<0)
1622+#define FBC_CONTROL2 0x03214
1623+#define FBC_CTL_FENCE_DBL (0<<4)
1624+#define FBC_CTL_IDLE_IMM (0<<2)
1625+#define FBC_CTL_IDLE_FULL (1<<2)
1626+#define FBC_CTL_IDLE_LINE (2<<2)
1627+#define FBC_CTL_IDLE_DEBUG (3<<2)
1628+#define FBC_CTL_CPU_FENCE (1<<1)
1629+#define FBC_CTL_PLANEA (0<<0)
1630+#define FBC_CTL_PLANEB (1<<0)
1631+#define FBC_FENCE_OFF 0x0321b
1632+
1633+#define FBC_LL_SIZE (1536)
1634+
1635+/*
1636+ * GPIO regs
1637+ */
1638+#define GPIOA 0x5010
1639+#define GPIOB 0x5014
1640+#define GPIOC 0x5018
1641+#define GPIOD 0x501c
1642+#define GPIOE 0x5020
1643+#define GPIOF 0x5024
1644+#define GPIOG 0x5028
1645+#define GPIOH 0x502c
1646+# define GPIO_CLOCK_DIR_MASK (1 << 0)
1647+# define GPIO_CLOCK_DIR_IN (0 << 1)
1648+# define GPIO_CLOCK_DIR_OUT (1 << 1)
1649+# define GPIO_CLOCK_VAL_MASK (1 << 2)
1650+# define GPIO_CLOCK_VAL_OUT (1 << 3)
1651+# define GPIO_CLOCK_VAL_IN (1 << 4)
1652+# define GPIO_CLOCK_PULLUP_DISABLE (1 << 5)
1653+# define GPIO_DATA_DIR_MASK (1 << 8)
1654+# define GPIO_DATA_DIR_IN (0 << 9)
1655+# define GPIO_DATA_DIR_OUT (1 << 9)
1656+# define GPIO_DATA_VAL_MASK (1 << 10)
1657+# define GPIO_DATA_VAL_OUT (1 << 11)
1658+# define GPIO_DATA_VAL_IN (1 << 12)
1659+# define GPIO_DATA_PULLUP_DISABLE (1 << 13)
1660+
1661+/*
1662+ * Clock control & power management
1663+ */
1664+
1665+#define VGA0 0x6000
1666+#define VGA1 0x6004
1667+#define VGA_PD 0x6010
1668+#define VGA0_PD_P2_DIV_4 (1 << 7)
1669+#define VGA0_PD_P1_DIV_2 (1 << 5)
1670+#define VGA0_PD_P1_SHIFT 0
1671+#define VGA0_PD_P1_MASK (0x1f << 0)
1672+#define VGA1_PD_P2_DIV_4 (1 << 15)
1673+#define VGA1_PD_P1_DIV_2 (1 << 13)
1674+#define VGA1_PD_P1_SHIFT 8
1675+#define VGA1_PD_P1_MASK (0x1f << 8)
1676+#define DPLL_A 0x06014
1677+#define DPLL_B 0x06018
1678+#define DPLL_VCO_ENABLE (1 << 31)
1679+#define DPLL_DVO_HIGH_SPEED (1 << 30)
1680+#define DPLL_SYNCLOCK_ENABLE (1 << 29)
1681+#define DPLL_VGA_MODE_DIS (1 << 28)
1682+#define DPLLB_MODE_DAC_SERIAL (1 << 26) /* i915 */
1683+#define DPLLB_MODE_LVDS (2 << 26) /* i915 */
1684+#define DPLL_MODE_MASK (3 << 26)
1685+#define DPLL_DAC_SERIAL_P2_CLOCK_DIV_10 (0 << 24) /* i915 */
1686+#define DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 (1 << 24) /* i915 */
1687+#define DPLLB_LVDS_P2_CLOCK_DIV_14 (0 << 24) /* i915 */
1688+#define DPLLB_LVDS_P2_CLOCK_DIV_7 (1 << 24) /* i915 */
1689+#define DPLL_P2_CLOCK_DIV_MASK 0x03000000 /* i915 */
1690+#define DPLL_FPA01_P1_POST_DIV_MASK 0x00ff0000 /* i915 */
1691+
1692+#define I915_FIFO_UNDERRUN_STATUS (1UL<<31)
1693+#define I915_CRC_ERROR_ENABLE (1UL<<29)
1694+#define I915_CRC_DONE_ENABLE (1UL<<28)
1695+#define I915_GMBUS_EVENT_ENABLE (1UL<<27)
1696+#define I915_VSYNC_INTERRUPT_ENABLE (1UL<<25)
1697+#define I915_DISPLAY_LINE_COMPARE_ENABLE (1UL<<24)
1698+#define I915_DPST_EVENT_ENABLE (1UL<<23)
1699+#define I915_LEGACY_BLC_EVENT_ENABLE (1UL<<22)
1700+#define I915_ODD_FIELD_INTERRUPT_ENABLE (1UL<<21)
1701+#define I915_EVEN_FIELD_INTERRUPT_ENABLE (1UL<<20)
1702+#define I915_START_VBLANK_INTERRUPT_ENABLE (1UL<<18) /* 965 or later */
1703+#define I915_VBLANK_INTERRUPT_ENABLE (1UL<<17)
1704+#define I915_OVERLAY_UPDATED_ENABLE (1UL<<16)
1705+#define I915_CRC_ERROR_INTERRUPT_STATUS (1UL<<13)
1706+#define I915_CRC_DONE_INTERRUPT_STATUS (1UL<<12)
1707+#define I915_GMBUS_INTERRUPT_STATUS (1UL<<11)
1708+#define I915_VSYNC_INTERRUPT_STATUS (1UL<<9)
1709+#define I915_DISPLAY_LINE_COMPARE_STATUS (1UL<<8)
1710+#define I915_DPST_EVENT_STATUS (1UL<<7)
1711+#define I915_LEGACY_BLC_EVENT_STATUS (1UL<<6)
1712+#define I915_ODD_FIELD_INTERRUPT_STATUS (1UL<<5)
1713+#define I915_EVEN_FIELD_INTERRUPT_STATUS (1UL<<4)
1714+#define I915_START_VBLANK_INTERRUPT_STATUS (1UL<<2) /* 965 or later */
1715+#define I915_VBLANK_INTERRUPT_STATUS (1UL<<1)
1716+#define I915_OVERLAY_UPDATED_STATUS (1UL<<0)
1717+
1718+#define SRX_INDEX 0x3c4
1719+#define SRX_DATA 0x3c5
1720+#define SR01 1
1721+#define SR01_SCREEN_OFF (1<<5)
1722+
1723+#define PPCR 0x61204
1724+#define PPCR_ON (1<<0)
1725+
1726+#define DVOB 0x61140
1727+#define DVOB_ON (1<<31)
1728+#define DVOC 0x61160
1729+#define DVOC_ON (1<<31)
1730+#define LVDS 0x61180
1731+#define LVDS_ON (1<<31)
1732+
1733+#define ADPA 0x61100
1734+#define ADPA_DPMS_MASK (~(3<<10))
1735+#define ADPA_DPMS_ON (0<<10)
1736+#define ADPA_DPMS_SUSPEND (1<<10)
1737+#define ADPA_DPMS_STANDBY (2<<10)
1738+#define ADPA_DPMS_OFF (3<<10)
1739+
1740+#define RING_TAIL 0x00
1741+#define TAIL_ADDR 0x001FFFF8
1742+#define RING_HEAD 0x04
1743+#define HEAD_WRAP_COUNT 0xFFE00000
1744+#define HEAD_WRAP_ONE 0x00200000
1745+#define HEAD_ADDR 0x001FFFFC
1746+#define RING_START 0x08
1747+#define START_ADDR 0xFFFFF000
1748+#define RING_LEN 0x0C
1749+#define RING_NR_PAGES 0x001FF000
1750+#define RING_REPORT_MASK 0x00000006
1751+#define RING_REPORT_64K 0x00000002
1752+#define RING_REPORT_128K 0x00000004
1753+#define RING_NO_REPORT 0x00000000
1754+#define RING_VALID_MASK 0x00000001
1755+#define RING_VALID 0x00000001
1756+#define RING_INVALID 0x00000000
1757+
1758+/* Scratch pad debug 0 reg:
1759+ */
1760+#define DPLL_FPA01_P1_POST_DIV_MASK_I830 0x001f0000
1761+/*
1762+ * The i830 generation, in LVDS mode, defines P1 as the bit number set within
1763+ * this field (only one bit may be set).
1764+ */
1765+#define DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS 0x003f0000
1766+#define DPLL_FPA01_P1_POST_DIV_SHIFT 16
1767+/* i830, required in DVO non-gang */
1768+#define PLL_P2_DIVIDE_BY_4 (1 << 23)
1769+#define PLL_P1_DIVIDE_BY_TWO (1 << 21) /* i830 */
1770+#define PLL_REF_INPUT_DREFCLK (0 << 13)
1771+#define PLL_REF_INPUT_TVCLKINA (1 << 13) /* i830 */
1772+#define PLL_REF_INPUT_TVCLKINBC (2 << 13) /* SDVO TVCLKIN */
1773+#define PLLB_REF_INPUT_SPREADSPECTRUMIN (3 << 13)
1774+#define PLL_REF_INPUT_MASK (3 << 13)
1775+#define PLL_LOAD_PULSE_PHASE_SHIFT 9
1776+/*
1777+ * Parallel to Serial Load Pulse phase selection.
1778+ * Selects the phase for the 10X DPLL clock for the PCIe
1779+ * digital display port. The range is 4 to 13; 10 or more
1780+ * is just a flip delay. The default is 6
1781+ */
1782+#define PLL_LOAD_PULSE_PHASE_MASK (0xf << PLL_LOAD_PULSE_PHASE_SHIFT)
1783+#define DISPLAY_RATE_SELECT_FPA1 (1 << 8)
1784+/*
1785+ * SDVO multiplier for 945G/GM. Not used on 965.
1786+ */
1787+#define SDVO_MULTIPLIER_MASK 0x000000ff
1788+#define SDVO_MULTIPLIER_SHIFT_HIRES 4
1789+#define SDVO_MULTIPLIER_SHIFT_VGA 0
1790+#define DPLL_A_MD 0x0601c /* 965+ only */
1791+/*
1792+ * UDI pixel divider, controlling how many pixels are stuffed into a packet.
1793+ *
1794+ * Value is pixels minus 1. Must be set to 1 pixel for SDVO.
1795+ */
1796+#define DPLL_MD_UDI_DIVIDER_MASK 0x3f000000
1797+#define DPLL_MD_UDI_DIVIDER_SHIFT 24
1798+/* UDI pixel divider for VGA, same as DPLL_MD_UDI_DIVIDER_MASK. */
1799+#define DPLL_MD_VGA_UDI_DIVIDER_MASK 0x003f0000
1800+#define DPLL_MD_VGA_UDI_DIVIDER_SHIFT 16
1801+/*
1802+ * SDVO/UDI pixel multiplier.
1803+ *
1804+ * SDVO requires that the bus clock rate be between 1 and 2 Ghz, and the bus
1805+ * clock rate is 10 times the DPLL clock. At low resolution/refresh rate
1806+ * modes, the bus rate would be below the limits, so SDVO allows for stuffing
1807+ * dummy bytes in the datastream at an increased clock rate, with both sides of
1808+ * the link knowing how many bytes are fill.
1809+ *
1810+ * So, for a mode with a dotclock of 65Mhz, we would want to double the clock
1811+ * rate to 130Mhz to get a bus rate of 1.30Ghz. The DPLL clock rate would be
1812+ * set to 130Mhz, and the SDVO multiplier set to 2x in this register and
1813+ * through an SDVO command.
1814+ *
1815+ * This register field has values of multiplication factor minus 1, with
1816+ * a maximum multiplier of 5 for SDVO.
1817+ */
1818+#define DPLL_MD_UDI_MULTIPLIER_MASK 0x00003f00
1819+#define DPLL_MD_UDI_MULTIPLIER_SHIFT 8
1820+/*
1821+ * SDVO/UDI pixel multiplier for VGA, same as DPLL_MD_UDI_MULTIPLIER_MASK.
1822+ * This best be set to the default value (3) or the CRT won't work. No,
1823+ * I don't entirely understand what this does...
1824+ */
1825+#define DPLL_MD_VGA_UDI_MULTIPLIER_MASK 0x0000003f
1826+#define DPLL_MD_VGA_UDI_MULTIPLIER_SHIFT 0
1827+#define DPLL_B_MD 0x06020 /* 965+ only */
1828+#define FPA0 0x06040
1829+#define FPA1 0x06044
1830+#define FPB0 0x06048
1831+#define FPB1 0x0604c
1832+#define FP_N_DIV_MASK 0x003f0000
1833+#define FP_N_DIV_SHIFT 16
1834+#define FP_M1_DIV_MASK 0x00003f00
1835+#define FP_M1_DIV_SHIFT 8
1836+#define FP_M2_DIV_MASK 0x0000003f
1837+#define FP_M2_DIV_SHIFT 0
1838+#define DPLL_TEST 0x606c
1839+#define DPLLB_TEST_SDVO_DIV_1 (0 << 22)
1840+#define DPLLB_TEST_SDVO_DIV_2 (1 << 22)
1841+#define DPLLB_TEST_SDVO_DIV_4 (2 << 22)
1842+#define DPLLB_TEST_SDVO_DIV_MASK (3 << 22)
1843+#define DPLLB_TEST_N_BYPASS (1 << 19)
1844+#define DPLLB_TEST_M_BYPASS (1 << 18)
1845+#define DPLLB_INPUT_BUFFER_ENABLE (1 << 16)
1846+#define DPLLA_TEST_N_BYPASS (1 << 3)
1847+#define DPLLA_TEST_M_BYPASS (1 << 2)
1848+#define DPLLA_INPUT_BUFFER_ENABLE (1 << 0)
1849+#define D_STATE 0x6104
1850+#define CG_2D_DIS 0x6200
1851+#define CG_3D_DIS 0x6204
1852+
1853+/*
1854+ * Palette regs
1855+ */
1856+
1857+#define PALETTE_A 0x0a000
1858+#define PALETTE_B 0x0a800
1859+
1860+/*
1861+ * Overlay regs
1862+ */
1863+
1864+#define OVADD 0x30000
1865+#define DOVSTA 0x30008
1866+#define OC_BUF (0x3<<20)
1867+#define OGAMC5 0x30010
1868+#define OGAMC4 0x30014
1869+#define OGAMC3 0x30018
1870+#define OGAMC2 0x3001c
1871+#define OGAMC1 0x30020
1872+#define OGAMC0 0x30024
1873+
1874+/*
1875+ * Display engine regs
1876+ */
1877+
1878+/* Pipe A timing regs */
1879+#define HTOTAL_A 0x60000
1880+#define HBLANK_A 0x60004
1881+#define HSYNC_A 0x60008
1882+#define VTOTAL_A 0x6000c
1883+#define VBLANK_A 0x60010
1884+#define VSYNC_A 0x60014
1885+#define PIPEASRC 0x6001c
1886+#define BCLRPAT_A 0x60020
1887+
1888+/* Pipe B timing regs */
1889+#define HTOTAL_B 0x61000
1890+#define HBLANK_B 0x61004
1891+#define HSYNC_B 0x61008
1892+#define VTOTAL_B 0x6100c
1893+#define VBLANK_B 0x61010
1894+#define VSYNC_B 0x61014
1895+#define PIPEBSRC 0x6101c
1896+#define BCLRPAT_B 0x61020
1897+
1898+/* VGA port control */
1899+#define ADPA 0x61100
1900+#define ADPA_DAC_ENABLE (1<<31)
1901+#define ADPA_DAC_DISABLE 0
1902+#define ADPA_PIPE_SELECT_MASK (1<<30)
1903+#define ADPA_PIPE_A_SELECT 0
1904+#define ADPA_PIPE_B_SELECT (1<<30)
1905+#define ADPA_USE_VGA_HVPOLARITY (1<<15)
1906+#define ADPA_SETS_HVPOLARITY 0
1907+#define ADPA_VSYNC_CNTL_DISABLE (1<<11)
1908+#define ADPA_VSYNC_CNTL_ENABLE 0
1909+#define ADPA_HSYNC_CNTL_DISABLE (1<<10)
1910+#define ADPA_HSYNC_CNTL_ENABLE 0
1911+#define ADPA_VSYNC_ACTIVE_HIGH (1<<4)
1912+#define ADPA_VSYNC_ACTIVE_LOW 0
1913+#define ADPA_HSYNC_ACTIVE_HIGH (1<<3)
1914+#define ADPA_HSYNC_ACTIVE_LOW 0
1915+#define ADPA_DPMS_MASK (~(3<<10))
1916+#define ADPA_DPMS_ON (0<<10)
1917+#define ADPA_DPMS_SUSPEND (1<<10)
1918+#define ADPA_DPMS_STANDBY (2<<10)
1919+#define ADPA_DPMS_OFF (3<<10)
1920+
1921+/* Hotplug control (945+ only) */
1922+#define PORT_HOTPLUG_EN 0x61110
1923+#define SDVOB_HOTPLUG_INT_EN (1 << 26)
1924+#define SDVOC_HOTPLUG_INT_EN (1 << 25)
1925+#define TV_HOTPLUG_INT_EN (1 << 18)
1926+#define CRT_HOTPLUG_INT_EN (1 << 9)
1927+#define CRT_HOTPLUG_FORCE_DETECT (1 << 3)
1928+
1929+#define PORT_HOTPLUG_STAT 0x61114
1930+#define CRT_HOTPLUG_INT_STATUS (1 << 11)
1931+#define TV_HOTPLUG_INT_STATUS (1 << 10)
1932+#define CRT_HOTPLUG_MONITOR_MASK (3 << 8)
1933+#define CRT_HOTPLUG_MONITOR_COLOR (3 << 8)
1934+#define CRT_HOTPLUG_MONITOR_MONO (2 << 8)
1935+#define CRT_HOTPLUG_MONITOR_NONE (0 << 8)
1936+#define SDVOC_HOTPLUG_INT_STATUS (1 << 7)
1937+#define SDVOB_HOTPLUG_INT_STATUS (1 << 6)
1938+
1939+/* SDVO port control */
1940+#define SDVOB 0x61140
1941+#define SDVOC 0x61160
1942+#define SDVO_ENABLE (1 << 31)
1943+#define SDVO_PIPE_B_SELECT (1 << 30)
1944+#define SDVO_STALL_SELECT (1 << 29)
1945+#define SDVO_INTERRUPT_ENABLE (1 << 26)
1946+/**
1947+ * 915G/GM SDVO pixel multiplier.
1948+ *
1949+ * Programmed value is multiplier - 1, up to 5x.
1950+ *
1951+ * \sa DPLL_MD_UDI_MULTIPLIER_MASK
1952+ */
1953+#define SDVO_PORT_MULTIPLY_MASK (7 << 23)
1954+#define SDVO_PORT_MULTIPLY_SHIFT 23
1955+#define SDVO_PHASE_SELECT_MASK (15 << 19)
1956+#define SDVO_PHASE_SELECT_DEFAULT (6 << 19)
1957+#define SDVO_CLOCK_OUTPUT_INVERT (1 << 18)
1958+#define SDVOC_GANG_MODE (1 << 16)
1959+#define SDVO_BORDER_ENABLE (1 << 7)
1960+#define SDVOB_PCIE_CONCURRENCY (1 << 3)
1961+#define SDVO_DETECTED (1 << 2)
1962+/* Bits to be preserved when writing */
1963+#define SDVOB_PRESERVE_MASK ((1 << 17) | (1 << 16) | (1 << 14) | (1 << 26))
1964+#define SDVOC_PRESERVE_MASK ((1 << 17) | (1 << 26))
1965+
1966+/* DVO port control */
1967+#define DVOA 0x61120
1968+#define DVOB 0x61140
1969+#define DVOC 0x61160
1970+#define DVO_ENABLE (1 << 31)
1971+#define DVO_PIPE_B_SELECT (1 << 30)
1972+#define DVO_PIPE_STALL_UNUSED (0 << 28)
1973+#define DVO_PIPE_STALL (1 << 28)
1974+#define DVO_PIPE_STALL_TV (2 << 28)
1975+#define DVO_PIPE_STALL_MASK (3 << 28)
1976+#define DVO_USE_VGA_SYNC (1 << 15)
1977+#define DVO_DATA_ORDER_I740 (0 << 14)
1978+#define DVO_DATA_ORDER_FP (1 << 14)
1979+#define DVO_VSYNC_DISABLE (1 << 11)
1980+#define DVO_HSYNC_DISABLE (1 << 10)
1981+#define DVO_VSYNC_TRISTATE (1 << 9)
1982+#define DVO_HSYNC_TRISTATE (1 << 8)
1983+#define DVO_BORDER_ENABLE (1 << 7)
1984+#define DVO_DATA_ORDER_GBRG (1 << 6)
1985+#define DVO_DATA_ORDER_RGGB (0 << 6)
1986+#define DVO_DATA_ORDER_GBRG_ERRATA (0 << 6)
1987+#define DVO_DATA_ORDER_RGGB_ERRATA (1 << 6)
1988+#define DVO_VSYNC_ACTIVE_HIGH (1 << 4)
1989+#define DVO_HSYNC_ACTIVE_HIGH (1 << 3)
1990+#define DVO_BLANK_ACTIVE_HIGH (1 << 2)
1991+#define DVO_OUTPUT_CSTATE_PIXELS (1 << 1) /* SDG only */
1992+#define DVO_OUTPUT_SOURCE_SIZE_PIXELS (1 << 0) /* SDG only */
1993+#define DVO_PRESERVE_MASK (0x7<<24)
1994+#define DVOA_SRCDIM 0x61124
1995+#define DVOB_SRCDIM 0x61144
1996+#define DVOC_SRCDIM 0x61164
1997+#define DVO_SRCDIM_HORIZONTAL_SHIFT 12
1998+#define DVO_SRCDIM_VERTICAL_SHIFT 0
1999+
2000+/* LVDS port control */
2001+#define LVDS 0x61180
2002+/*
2003+ * Enables the LVDS port. This bit must be set before DPLLs are enabled, as
2004+ * the DPLL semantics change when the LVDS is assigned to that pipe.
2005+ */
2006+#define LVDS_PORT_EN (1 << 31)
2007+/* Selects pipe B for LVDS data. Must be set on pre-965. */
2008+#define LVDS_PIPEB_SELECT (1 << 30)
2009+/*
2010+ * Enables the A0-A2 data pairs and CLKA, containing 18 bits of color data per
2011+ * pixel.
2012+ */
2013+#define LVDS_A0A2_CLKA_POWER_MASK (3 << 8)
2014+#define LVDS_A0A2_CLKA_POWER_DOWN (0 << 8)
2015+#define LVDS_A0A2_CLKA_POWER_UP (3 << 8)
2016+/*
2017+ * Controls the A3 data pair, which contains the additional LSBs for 24 bit
2018+ * mode. Only enabled if LVDS_A0A2_CLKA_POWER_UP also indicates it should be
2019+ * on.
2020+ */
2021+#define LVDS_A3_POWER_MASK (3 << 6)
2022+#define LVDS_A3_POWER_DOWN (0 << 6)
2023+#define LVDS_A3_POWER_UP (3 << 6)
2024+/*
2025+ * Controls the CLKB pair. This should only be set when LVDS_B0B3_POWER_UP
2026+ * is set.
2027+ */
2028+#define LVDS_CLKB_POWER_MASK (3 << 4)
2029+#define LVDS_CLKB_POWER_DOWN (0 << 4)
2030+#define LVDS_CLKB_POWER_UP (3 << 4)
2031+/*
2032+ * Controls the B0-B3 data pairs. This must be set to match the DPLL p2
2033+ * setting for whether we are in dual-channel mode. The B3 pair will
2034+ * additionally only be powered up when LVDS_A3_POWER_UP is set.
2035+ */
2036+#define LVDS_B0B3_POWER_MASK (3 << 2)
2037+#define LVDS_B0B3_POWER_DOWN (0 << 2)
2038+#define LVDS_B0B3_POWER_UP (3 << 2)
2039+
2040+/* Panel power sequencing */
2041+#define PP_STATUS 0x61200
2042+#define PP_ON (1 << 31)
2043+/*
2044+ * Indicates that all dependencies of the panel are on:
2045+ *
2046+ * - PLL enabled
2047+ * - pipe enabled
2048+ * - LVDS/DVOB/DVOC on
2049+ */
2050+#define PP_READY (1 << 30)
2051+#define PP_SEQUENCE_NONE (0 << 28)
2052+#define PP_SEQUENCE_ON (1 << 28)
2053+#define PP_SEQUENCE_OFF (2 << 28)
2054+#define PP_SEQUENCE_MASK 0x30000000
2055+#define PP_CONTROL 0x61204
2056+#define POWER_TARGET_ON (1 << 0)
2057+#define PP_ON_DELAYS 0x61208
2058+#define PP_OFF_DELAYS 0x6120c
2059+#define PP_DIVISOR 0x61210
2060+
2061+/* Panel fitting */
2062+#define PFIT_CONTROL 0x61230
2063+#define PFIT_ENABLE (1 << 31)
2064+#define PFIT_PIPE_MASK (3 << 29)
2065+#define PFIT_PIPE_SHIFT 29
2066+#define VERT_INTERP_DISABLE (0 << 10)
2067+#define VERT_INTERP_BILINEAR (1 << 10)
2068+#define VERT_INTERP_MASK (3 << 10)
2069+#define VERT_AUTO_SCALE (1 << 9)
2070+#define HORIZ_INTERP_DISABLE (0 << 6)
2071+#define HORIZ_INTERP_BILINEAR (1 << 6)
2072+#define HORIZ_INTERP_MASK (3 << 6)
2073+#define HORIZ_AUTO_SCALE (1 << 5)
2074+#define PANEL_8TO6_DITHER_ENABLE (1 << 3)
2075+#define PFIT_PGM_RATIOS 0x61234
2076+#define PFIT_VERT_SCALE_MASK 0xfff00000
2077+#define PFIT_HORIZ_SCALE_MASK 0x0000fff0
2078+#define PFIT_AUTO_RATIOS 0x61238
2079+
2080+/* Backlight control */
2081+#define BLC_PWM_CTL 0x61254
2082+#define BACKLIGHT_MODULATION_FREQ_SHIFT (17)
2083+#define BLC_PWM_CTL2 0x61250 /* 965+ only */
2084+/*
2085+ * This is the most significant 15 bits of the number of backlight cycles in a
2086+ * complete cycle of the modulated backlight control.
2087+ *
2088+ * The actual value is this field multiplied by two.
2089+ */
2090+#define BACKLIGHT_MODULATION_FREQ_MASK (0x7fff << 17)
2091+#define BLM_LEGACY_MODE (1 << 16)
2092+/*
2093+ * This is the number of cycles out of the backlight modulation cycle for which
2094+ * the backlight is on.
2095+ *
2096+ * This field must be no greater than the number of cycles in the complete
2097+ * backlight modulation cycle.
2098+ */
2099+#define BACKLIGHT_DUTY_CYCLE_SHIFT (0)
2100+#define BACKLIGHT_DUTY_CYCLE_MASK (0xffff)
2101+
2102+/* TV port control */
2103+#define TV_CTL 0x68000
2104+/** Enables the TV encoder */
2105+# define TV_ENC_ENABLE (1 << 31)
2106+/** Sources the TV encoder input from pipe B instead of A. */
2107+# define TV_ENC_PIPEB_SELECT (1 << 30)
2108+/** Outputs composite video (DAC A only) */
2109+# define TV_ENC_OUTPUT_COMPOSITE (0 << 28)
2110+/** Outputs SVideo video (DAC B/C) */
2111+# define TV_ENC_OUTPUT_SVIDEO (1 << 28)
2112+/** Outputs Component video (DAC A/B/C) */
2113+# define TV_ENC_OUTPUT_COMPONENT (2 << 28)
2114+/** Outputs Composite and SVideo (DAC A/B/C) */
2115+# define TV_ENC_OUTPUT_SVIDEO_COMPOSITE (3 << 28)
2116+# define TV_TRILEVEL_SYNC (1 << 21)
2117+/** Enables slow sync generation (945GM only) */
2118+# define TV_SLOW_SYNC (1 << 20)
2119+/** Selects 4x oversampling for 480i and 576p */
2120+# define TV_OVERSAMPLE_4X (0 << 18)
2121+/** Selects 2x oversampling for 720p and 1080i */
2122+# define TV_OVERSAMPLE_2X (1 << 18)
2123+/** Selects no oversampling for 1080p */
2124+# define TV_OVERSAMPLE_NONE (2 << 18)
2125+/** Selects 8x oversampling */
2126+# define TV_OVERSAMPLE_8X (3 << 18)
2127+/** Selects progressive mode rather than interlaced */
2128+# define TV_PROGRESSIVE (1 << 17)
2129+/** Sets the colorburst to PAL mode. Required for non-M PAL modes. */
2130+# define TV_PAL_BURST (1 << 16)
2131+/** Field for setting delay of Y compared to C */
2132+# define TV_YC_SKEW_MASK (7 << 12)
2133+/** Enables a fix for 480p/576p standard definition modes on the 915GM only */
2134+# define TV_ENC_SDP_FIX (1 << 11)
2135+/**
2136+ * Enables a fix for the 915GM only.
2137+ *
2138+ * Not sure what it does.
2139+ */
2140+# define TV_ENC_C0_FIX (1 << 10)
2141+/** Bits that must be preserved by software */
2142+# define TV_CTL_SAVE ((3 << 8) | (3 << 6))
2143+# define TV_FUSE_STATE_MASK (3 << 4)
2144+/** Read-only state that reports all features enabled */
2145+# define TV_FUSE_STATE_ENABLED (0 << 4)
2146+/** Read-only state that reports that Macrovision is disabled in hardware*/
2147+# define TV_FUSE_STATE_NO_MACROVISION (1 << 4)
2148+/** Read-only state that reports that TV-out is disabled in hardware. */
2149+# define TV_FUSE_STATE_DISABLED (2 << 4)
2150+/** Normal operation */
2151+# define TV_TEST_MODE_NORMAL (0 << 0)
2152+/** Encoder test pattern 1 - combo pattern */
2153+# define TV_TEST_MODE_PATTERN_1 (1 << 0)
2154+/** Encoder test pattern 2 - full screen vertical 75% color bars */
2155+# define TV_TEST_MODE_PATTERN_2 (2 << 0)
2156+/** Encoder test pattern 3 - full screen horizontal 75% color bars */
2157+# define TV_TEST_MODE_PATTERN_3 (3 << 0)
2158+/** Encoder test pattern 4 - random noise */
2159+# define TV_TEST_MODE_PATTERN_4 (4 << 0)
2160+/** Encoder test pattern 5 - linear color ramps */
2161+# define TV_TEST_MODE_PATTERN_5 (5 << 0)
2162+/**
2163+ * This test mode forces the DACs to 50% of full output.
2164+ *
2165+ * This is used for load detection in combination with TVDAC_SENSE_MASK
2166+ */
2167+# define TV_TEST_MODE_MONITOR_DETECT (7 << 0)
2168+# define TV_TEST_MODE_MASK (7 << 0)
2169+
2170+#define TV_DAC 0x68004
2171+/**
2172+ * Reports that DAC state change logic has reported change (RO).
2173+ *
2174+ * This gets cleared when TV_DAC_STATE_EN is cleared
2175+*/
2176+# define TVDAC_STATE_CHG (1 << 31)
2177+# define TVDAC_SENSE_MASK (7 << 28)
2178+/** Reports that DAC A voltage is above the detect threshold */
2179+# define TVDAC_A_SENSE (1 << 30)
2180+/** Reports that DAC B voltage is above the detect threshold */
2181+# define TVDAC_B_SENSE (1 << 29)
2182+/** Reports that DAC C voltage is above the detect threshold */
2183+# define TVDAC_C_SENSE (1 << 28)
2184+/**
2185+ * Enables DAC state detection logic, for load-based TV detection.
2186+ *
2187+ * The PLL of the chosen pipe (in TV_CTL) must be running, and the encoder set
2188+ * to off, for load detection to work.
2189+ */
2190+# define TVDAC_STATE_CHG_EN (1 << 27)
2191+/** Sets the DAC A sense value to high */
2192+# define TVDAC_A_SENSE_CTL (1 << 26)
2193+/** Sets the DAC B sense value to high */
2194+# define TVDAC_B_SENSE_CTL (1 << 25)
2195+/** Sets the DAC C sense value to high */
2196+# define TVDAC_C_SENSE_CTL (1 << 24)
2197+/** Overrides the ENC_ENABLE and DAC voltage levels */
2198+# define DAC_CTL_OVERRIDE (1 << 7)
2199+/** Sets the slew rate. Must be preserved in software */
2200+# define ENC_TVDAC_SLEW_FAST (1 << 6)
2201+# define DAC_A_1_3_V (0 << 4)
2202+# define DAC_A_1_1_V (1 << 4)
2203+# define DAC_A_0_7_V (2 << 4)
2204+# define DAC_A_OFF (3 << 4)
2205+# define DAC_B_1_3_V (0 << 2)
2206+# define DAC_B_1_1_V (1 << 2)
2207+# define DAC_B_0_7_V (2 << 2)
2208+# define DAC_B_OFF (3 << 2)
2209+# define DAC_C_1_3_V (0 << 0)
2210+# define DAC_C_1_1_V (1 << 0)
2211+# define DAC_C_0_7_V (2 << 0)
2212+# define DAC_C_OFF (3 << 0)
2213+
2214+/**
2215+ * CSC coefficients are stored in a floating point format with 9 bits of
2216+ * mantissa and 2 or 3 bits of exponent. The exponent is represented as 2**-n,
2217+ * where 2-bit exponents are unsigned n, and 3-bit exponents are signed n with
2218+ * -1 (0x3) being the only legal negative value.
2219+ */
2220+#define TV_CSC_Y 0x68010
2221+# define TV_RY_MASK 0x07ff0000
2222+# define TV_RY_SHIFT 16
2223+# define TV_GY_MASK 0x00000fff
2224+# define TV_GY_SHIFT 0
2225+
2226+#define TV_CSC_Y2 0x68014
2227+# define TV_BY_MASK 0x07ff0000
2228+# define TV_BY_SHIFT 16
2229+/**
2230+ * Y attenuation for component video.
2231+ *
2232+ * Stored in 1.9 fixed point.
2233+ */
2234+# define TV_AY_MASK 0x000003ff
2235+# define TV_AY_SHIFT 0
2236+
2237+#define TV_CSC_U 0x68018
2238+# define TV_RU_MASK 0x07ff0000
2239+# define TV_RU_SHIFT 16
2240+# define TV_GU_MASK 0x000007ff
2241+# define TV_GU_SHIFT 0
2242+
2243+#define TV_CSC_U2 0x6801c
2244+# define TV_BU_MASK 0x07ff0000
2245+# define TV_BU_SHIFT 16
2246+/**
2247+ * U attenuation for component video.
2248+ *
2249+ * Stored in 1.9 fixed point.
2250+ */
2251+# define TV_AU_MASK 0x000003ff
2252+# define TV_AU_SHIFT 0
2253+
2254+#define TV_CSC_V 0x68020
2255+# define TV_RV_MASK 0x0fff0000
2256+# define TV_RV_SHIFT 16
2257+# define TV_GV_MASK 0x000007ff
2258+# define TV_GV_SHIFT 0
2259+
2260+#define TV_CSC_V2 0x68024
2261+# define TV_BV_MASK 0x07ff0000
2262+# define TV_BV_SHIFT 16
2263+/**
2264+ * V attenuation for component video.
2265+ *
2266+ * Stored in 1.9 fixed point.
2267+ */
2268+# define TV_AV_MASK 0x000007ff
2269+# define TV_AV_SHIFT 0
2270+
2271+#define TV_CLR_KNOBS 0x68028
2272+/** 2s-complement brightness adjustment */
2273+# define TV_BRIGHTNESS_MASK 0xff000000
2274+# define TV_BRIGHTNESS_SHIFT 24
2275+/** Contrast adjustment, as a 2.6 unsigned floating point number */
2276+# define TV_CONTRAST_MASK 0x00ff0000
2277+# define TV_CONTRAST_SHIFT 16
2278+/** Saturation adjustment, as a 2.6 unsigned floating point number */
2279+# define TV_SATURATION_MASK 0x0000ff00
2280+# define TV_SATURATION_SHIFT 8
2281+/** Hue adjustment, as an integer phase angle in degrees */
2282+# define TV_HUE_MASK 0x000000ff
2283+# define TV_HUE_SHIFT 0
2284+
2285+#define TV_CLR_LEVEL 0x6802c
2286+/** Controls the DAC level for black */
2287+# define TV_BLACK_LEVEL_MASK 0x01ff0000
2288+# define TV_BLACK_LEVEL_SHIFT 16
2289+/** Controls the DAC level for blanking */
2290+# define TV_BLANK_LEVEL_MASK 0x000001ff
2291+# define TV_BLANK_LEVEL_SHIFT 0
2292+
2293+#define TV_H_CTL_1 0x68030
2294+/** Number of pixels in the hsync. */
2295+# define TV_HSYNC_END_MASK 0x1fff0000
2296+# define TV_HSYNC_END_SHIFT 16
2297+/** Total number of pixels minus one in the line (display and blanking). */
2298+# define TV_HTOTAL_MASK 0x00001fff
2299+# define TV_HTOTAL_SHIFT 0
2300+
2301+#define TV_H_CTL_2 0x68034
2302+/** Enables the colorburst (needed for non-component color) */
2303+# define TV_BURST_ENA (1 << 31)
2304+/** Offset of the colorburst from the start of hsync, in pixels minus one. */
2305+# define TV_HBURST_START_SHIFT 16
2306+# define TV_HBURST_START_MASK 0x1fff0000
2307+/** Length of the colorburst */
2308+# define TV_HBURST_LEN_SHIFT 0
2309+# define TV_HBURST_LEN_MASK 0x0001fff
2310+
2311+#define TV_H_CTL_3 0x68038
2312+/** End of hblank, measured in pixels minus one from start of hsync */
2313+# define TV_HBLANK_END_SHIFT 16
2314+# define TV_HBLANK_END_MASK 0x1fff0000
2315+/** Start of hblank, measured in pixels minus one from start of hsync */
2316+# define TV_HBLANK_START_SHIFT 0
2317+# define TV_HBLANK_START_MASK 0x0001fff
2318+
2319+#define TV_V_CTL_1 0x6803c
2320+/** XXX */
2321+# define TV_NBR_END_SHIFT 16
2322+# define TV_NBR_END_MASK 0x07ff0000
2323+/** XXX */
2324+# define TV_VI_END_F1_SHIFT 8
2325+# define TV_VI_END_F1_MASK 0x00003f00
2326+/** XXX */
2327+# define TV_VI_END_F2_SHIFT 0
2328+# define TV_VI_END_F2_MASK 0x0000003f
2329+
2330+#define TV_V_CTL_2 0x68040
2331+/** Length of vsync, in half lines */
2332+# define TV_VSYNC_LEN_MASK 0x07ff0000
2333+# define TV_VSYNC_LEN_SHIFT 16
2334+/** Offset of the start of vsync in field 1, measured in one less than the
2335+ * number of half lines.
2336+ */
2337+# define TV_VSYNC_START_F1_MASK 0x00007f00
2338+# define TV_VSYNC_START_F1_SHIFT 8
2339+/**
2340+ * Offset of the start of vsync in field 2, measured in one less than the
2341+ * number of half lines.
2342+ */
2343+# define TV_VSYNC_START_F2_MASK 0x0000007f
2344+# define TV_VSYNC_START_F2_SHIFT 0
2345+
2346+#define TV_V_CTL_3 0x68044
2347+/** Enables generation of the equalization signal */
2348+# define TV_EQUAL_ENA (1 << 31)
2349+/** Length of vsync, in half lines */
2350+# define TV_VEQ_LEN_MASK 0x007f0000
2351+# define TV_VEQ_LEN_SHIFT 16
2352+/** Offset of the start of equalization in field 1, measured in one less than
2353+ * the number of half lines.
2354+ */
2355+# define TV_VEQ_START_F1_MASK 0x0007f00
2356+# define TV_VEQ_START_F1_SHIFT 8
2357+/**
2358+ * Offset of the start of equalization in field 2, measured in one less than
2359+ * the number of half lines.
2360+ */
2361+# define TV_VEQ_START_F2_MASK 0x000007f
2362+# define TV_VEQ_START_F2_SHIFT 0
2363+
2364+#define TV_V_CTL_4 0x68048
2365+/**
2366+ * Offset to start of vertical colorburst, measured in one less than the
2367+ * number of lines from vertical start.
2368+ */
2369+# define TV_VBURST_START_F1_MASK 0x003f0000
2370+# define TV_VBURST_START_F1_SHIFT 16
2371+/**
2372+ * Offset to the end of vertical colorburst, measured in one less than the
2373+ * number of lines from the start of NBR.
2374+ */
2375+# define TV_VBURST_END_F1_MASK 0x000000ff
2376+# define TV_VBURST_END_F1_SHIFT 0
2377+
2378+#define TV_V_CTL_5 0x6804c
2379+/**
2380+ * Offset to start of vertical colorburst, measured in one less than the
2381+ * number of lines from vertical start.
2382+ */
2383+# define TV_VBURST_START_F2_MASK 0x003f0000
2384+# define TV_VBURST_START_F2_SHIFT 16
2385+/**
2386+ * Offset to the end of vertical colorburst, measured in one less than the
2387+ * number of lines from the start of NBR.
2388+ */
2389+# define TV_VBURST_END_F2_MASK 0x000000ff
2390+# define TV_VBURST_END_F2_SHIFT 0
2391+
2392+#define TV_V_CTL_6 0x68050
2393+/**
2394+ * Offset to start of vertical colorburst, measured in one less than the
2395+ * number of lines from vertical start.
2396+ */
2397+# define TV_VBURST_START_F3_MASK 0x003f0000
2398+# define TV_VBURST_START_F3_SHIFT 16
2399+/**
2400+ * Offset to the end of vertical colorburst, measured in one less than the
2401+ * number of lines from the start of NBR.
2402+ */
2403+# define TV_VBURST_END_F3_MASK 0x000000ff
2404+# define TV_VBURST_END_F3_SHIFT 0
2405+
2406+#define TV_V_CTL_7 0x68054
2407+/**
2408+ * Offset to start of vertical colorburst, measured in one less than the
2409+ * number of lines from vertical start.
2410+ */
2411+# define TV_VBURST_START_F4_MASK 0x003f0000
2412+# define TV_VBURST_START_F4_SHIFT 16
2413+/**
2414+ * Offset to the end of vertical colorburst, measured in one less than the
2415+ * number of lines from the start of NBR.
2416+ */
2417+# define TV_VBURST_END_F4_MASK 0x000000ff
2418+# define TV_VBURST_END_F4_SHIFT 0
2419+
2420+#define TV_SC_CTL_1 0x68060
2421+/** Turns on the first subcarrier phase generation DDA */
2422+# define TV_SC_DDA1_EN (1 << 31)
2423+/** Turns on the first subcarrier phase generation DDA */
2424+# define TV_SC_DDA2_EN (1 << 30)
2425+/** Turns on the first subcarrier phase generation DDA */
2426+# define TV_SC_DDA3_EN (1 << 29)
2427+/** Sets the subcarrier DDA to reset frequency every other field */
2428+# define TV_SC_RESET_EVERY_2 (0 << 24)
2429+/** Sets the subcarrier DDA to reset frequency every fourth field */
2430+# define TV_SC_RESET_EVERY_4 (1 << 24)
2431+/** Sets the subcarrier DDA to reset frequency every eighth field */
2432+# define TV_SC_RESET_EVERY_8 (2 << 24)
2433+/** Sets the subcarrier DDA to never reset the frequency */
2434+# define TV_SC_RESET_NEVER (3 << 24)
2435+/** Sets the peak amplitude of the colorburst.*/
2436+# define TV_BURST_LEVEL_MASK 0x00ff0000
2437+# define TV_BURST_LEVEL_SHIFT 16
2438+/** Sets the increment of the first subcarrier phase generation DDA */
2439+# define TV_SCDDA1_INC_MASK 0x00000fff
2440+# define TV_SCDDA1_INC_SHIFT 0
2441+
2442+#define TV_SC_CTL_2 0x68064
2443+/** Sets the rollover for the second subcarrier phase generation DDA */
2444+# define TV_SCDDA2_SIZE_MASK 0x7fff0000
2445+# define TV_SCDDA2_SIZE_SHIFT 16
2446+/** Sets the increent of the second subcarrier phase generation DDA */
2447+# define TV_SCDDA2_INC_MASK 0x00007fff
2448+# define TV_SCDDA2_INC_SHIFT 0
2449+
2450+#define TV_SC_CTL_3 0x68068
2451+/** Sets the rollover for the third subcarrier phase generation DDA */
2452+# define TV_SCDDA3_SIZE_MASK 0x7fff0000
2453+# define TV_SCDDA3_SIZE_SHIFT 16
2454+/** Sets the increent of the third subcarrier phase generation DDA */
2455+# define TV_SCDDA3_INC_MASK 0x00007fff
2456+# define TV_SCDDA3_INC_SHIFT 0
2457+
2458+#define TV_WIN_POS 0x68070
2459+/** X coordinate of the display from the start of horizontal active */
2460+# define TV_XPOS_MASK 0x1fff0000
2461+# define TV_XPOS_SHIFT 16
2462+/** Y coordinate of the display from the start of vertical active (NBR) */
2463+# define TV_YPOS_MASK 0x00000fff
2464+# define TV_YPOS_SHIFT 0
2465+
2466+#define TV_WIN_SIZE 0x68074
2467+/** Horizontal size of the display window, measured in pixels*/
2468+# define TV_XSIZE_MASK 0x1fff0000
2469+# define TV_XSIZE_SHIFT 16
2470+/**
2471+ * Vertical size of the display window, measured in pixels.
2472+ *
2473+ * Must be even for interlaced modes.
2474+ */
2475+# define TV_YSIZE_MASK 0x00000fff
2476+# define TV_YSIZE_SHIFT 0
2477+
2478+#define TV_FILTER_CTL_1 0x68080
2479+/**
2480+ * Enables automatic scaling calculation.
2481+ *
2482+ * If set, the rest of the registers are ignored, and the calculated values can
2483+ * be read back from the register.
2484+ */
2485+# define TV_AUTO_SCALE (1 << 31)
2486+/**
2487+ * Disables the vertical filter.
2488+ *
2489+ * This is required on modes more than 1024 pixels wide */
2490+# define TV_V_FILTER_BYPASS (1 << 29)
2491+/** Enables adaptive vertical filtering */
2492+# define TV_VADAPT (1 << 28)
2493+# define TV_VADAPT_MODE_MASK (3 << 26)
2494+/** Selects the least adaptive vertical filtering mode */
2495+# define TV_VADAPT_MODE_LEAST (0 << 26)
2496+/** Selects the moderately adaptive vertical filtering mode */
2497+# define TV_VADAPT_MODE_MODERATE (1 << 26)
2498+/** Selects the most adaptive vertical filtering mode */
2499+# define TV_VADAPT_MODE_MOST (3 << 26)
2500+/**
2501+ * Sets the horizontal scaling factor.
2502+ *
2503+ * This should be the fractional part of the horizontal scaling factor divided
2504+ * by the oversampling rate. TV_HSCALE should be less than 1, and set to:
2505+ *
2506+ * (src width - 1) / ((oversample * dest width) - 1)
2507+ */
2508+# define TV_HSCALE_FRAC_MASK 0x00003fff
2509+# define TV_HSCALE_FRAC_SHIFT 0
2510+
2511+#define TV_FILTER_CTL_2 0x68084
2512+/**
2513+ * Sets the integer part of the 3.15 fixed-point vertical scaling factor.
2514+ *
2515+ * TV_VSCALE should be (src height - 1) / ((interlace * dest height) - 1)
2516+ */
2517+# define TV_VSCALE_INT_MASK 0x00038000
2518+# define TV_VSCALE_INT_SHIFT 15
2519+/**
2520+ * Sets the fractional part of the 3.15 fixed-point vertical scaling factor.
2521+ *
2522+ * \sa TV_VSCALE_INT_MASK
2523+ */
2524+# define TV_VSCALE_FRAC_MASK 0x00007fff
2525+# define TV_VSCALE_FRAC_SHIFT 0
2526+
2527+#define TV_FILTER_CTL_3 0x68088
2528+/**
2529+ * Sets the integer part of the 3.15 fixed-point vertical scaling factor.
2530+ *
2531+ * TV_VSCALE should be (src height - 1) / (1/4 * (dest height - 1))
2532+ *
2533+ * For progressive modes, TV_VSCALE_IP_INT should be set to zeroes.
2534+ */
2535+# define TV_VSCALE_IP_INT_MASK 0x00038000
2536+# define TV_VSCALE_IP_INT_SHIFT 15
2537+/**
2538+ * Sets the fractional part of the 3.15 fixed-point vertical scaling factor.
2539+ *
2540+ * For progressive modes, TV_VSCALE_IP_INT should be set to zeroes.
2541+ *
2542+ * \sa TV_VSCALE_IP_INT_MASK
2543+ */
2544+# define TV_VSCALE_IP_FRAC_MASK 0x00007fff
2545+# define TV_VSCALE_IP_FRAC_SHIFT 0
2546+
2547+#define TV_CC_CONTROL 0x68090
2548+# define TV_CC_ENABLE (1 << 31)
2549+/**
2550+ * Specifies which field to send the CC data in.
2551+ *
2552+ * CC data is usually sent in field 0.
2553+ */
2554+# define TV_CC_FID_MASK (1 << 27)
2555+# define TV_CC_FID_SHIFT 27
2556+/** Sets the horizontal position of the CC data. Usually 135. */
2557+# define TV_CC_HOFF_MASK 0x03ff0000
2558+# define TV_CC_HOFF_SHIFT 16
2559+/** Sets the vertical position of the CC data. Usually 21 */
2560+# define TV_CC_LINE_MASK 0x0000003f
2561+# define TV_CC_LINE_SHIFT 0
2562+
2563+#define TV_CC_DATA 0x68094
2564+# define TV_CC_RDY (1 << 31)
2565+/** Second word of CC data to be transmitted. */
2566+# define TV_CC_DATA_2_MASK 0x007f0000
2567+# define TV_CC_DATA_2_SHIFT 16
2568+/** First word of CC data to be transmitted. */
2569+# define TV_CC_DATA_1_MASK 0x0000007f
2570+# define TV_CC_DATA_1_SHIFT 0
2571+
2572+#define TV_H_LUMA_0 0x68100
2573+#define TV_H_LUMA_59 0x681ec
2574+#define TV_H_CHROMA_0 0x68200
2575+#define TV_H_CHROMA_59 0x682ec
2576+#define TV_V_LUMA_0 0x68300
2577+#define TV_V_LUMA_42 0x683a8
2578+#define TV_V_CHROMA_0 0x68400
2579+#define TV_V_CHROMA_42 0x684a8
2580+
2581+/* Display & cursor control */
2582+
2583+/* Pipe A */
2584+#define PIPEADSL 0x70000
2585+#define PIPEACONF 0x70008
2586+#define PIPEACONF_ENABLE (1<<31)
2587+#define PIPEACONF_DISABLE 0
2588+#define PIPEACONF_DOUBLE_WIDE (1<<30)
2589+#define I965_PIPECONF_ACTIVE (1<<30)
2590+#define PIPEACONF_SINGLE_WIDE 0
2591+#define PIPEACONF_PIPE_UNLOCKED 0
2592+#define PIPEACONF_PIPE_LOCKED (1<<25)
2593+#define PIPEACONF_PALETTE 0
2594+#define PIPEACONF_GAMMA (1<<24)
2595+#define PIPECONF_FORCE_BORDER (1<<25)
2596+#define PIPECONF_PROGRESSIVE (0 << 21)
2597+#define PIPECONF_INTERLACE_W_FIELD_INDICATION (6 << 21)
2598+#define PIPECONF_INTERLACE_FIELD_0_ONLY (7 << 21)
2599+#define PIPEASTAT 0x70024
2600+#define PIPE_FIFO_UNDERRUN_STATUS (1UL<<31)
2601+#define PIPE_CRC_ERROR_ENABLE (1UL<<29)
2602+#define PIPE_CRC_DONE_ENABLE (1UL<<28)
2603+#define PIPE_GMBUS_EVENT_ENABLE (1UL<<27)
2604+#define PIPE_HOTPLUG_INTERRUPT_ENABLE (1UL<<26)
2605+#define PIPE_VSYNC_INTERRUPT_ENABLE (1UL<<25)
2606+#define PIPE_DISPLAY_LINE_COMPARE_ENABLE (1UL<<24)
2607+#define PIPE_DPST_EVENT_ENABLE (1UL<<23)
2608+#define PIPE_LEGACY_BLC_EVENT_ENABLE (1UL<<22)
2609+#define PIPE_ODD_FIELD_INTERRUPT_ENABLE (1UL<<21)
2610+#define PIPE_EVEN_FIELD_INTERRUPT_ENABLE (1UL<<20)
2611+#define PIPE_HOTPLUG_TV_INTERRUPT_ENABLE (1UL<<18) /* pre-965 */
2612+#define PIPE_START_VBLANK_INTERRUPT_ENABLE (1UL<<18) /* 965 or later */
2613+#define PIPE_VBLANK_INTERRUPT_ENABLE (1UL<<17)
2614+#define PIPE_OVERLAY_UPDATED_ENABLE (1UL<<16)
2615+#define PIPE_CRC_ERROR_INTERRUPT_STATUS (1UL<<13)
2616+#define PIPE_CRC_DONE_INTERRUPT_STATUS (1UL<<12)
2617+#define PIPE_GMBUS_INTERRUPT_STATUS (1UL<<11)
2618+#define PIPE_HOTPLUG_INTERRUPT_STATUS (1UL<<10)
2619+#define PIPE_VSYNC_INTERRUPT_STATUS (1UL<<9)
2620+#define PIPE_DISPLAY_LINE_COMPARE_STATUS (1UL<<8)
2621+#define PIPE_DPST_EVENT_STATUS (1UL<<7)
2622+#define PIPE_LEGACY_BLC_EVENT_STATUS (1UL<<6)
2623+#define PIPE_ODD_FIELD_INTERRUPT_STATUS (1UL<<5)
2624+#define PIPE_EVEN_FIELD_INTERRUPT_STATUS (1UL<<4)
2625+#define PIPE_HOTPLUG_TV_INTERRUPT_STATUS (1UL<<2) /* pre-965 */
2626+#define PIPE_START_VBLANK_INTERRUPT_STATUS (1UL<<2) /* 965 or later */
2627+#define PIPE_VBLANK_INTERRUPT_STATUS (1UL<<1)
2628+#define PIPE_OVERLAY_UPDATED_STATUS (1UL<<0)
2629+
2630+#define DSPARB 0x70030
2631+#define DSPARB_CSTART_MASK (0x7f << 7)
2632+#define DSPARB_CSTART_SHIFT 7
2633+#define DSPARB_BSTART_MASK (0x7f)
2634+#define DSPARB_BSTART_SHIFT 0
2635+/*
2636+ * The two pipe frame counter registers are not synchronized, so
2637+ * reading a stable value is somewhat tricky. The following code
2638+ * should work:
2639+ *
2640+ * do {
2641+ * high1 = ((INREG(PIPEAFRAMEHIGH) & PIPE_FRAME_HIGH_MASK) >>
2642+ * PIPE_FRAME_HIGH_SHIFT;
2643+ * low1 = ((INREG(PIPEAFRAMEPIXEL) & PIPE_FRAME_LOW_MASK) >>
2644+ * PIPE_FRAME_LOW_SHIFT);
2645+ * high2 = ((INREG(PIPEAFRAMEHIGH) & PIPE_FRAME_HIGH_MASK) >>
2646+ * PIPE_FRAME_HIGH_SHIFT);
2647+ * } while (high1 != high2);
2648+ * frame = (high1 << 8) | low1;
2649+ */
2650+#define PIPEAFRAMEHIGH 0x70040
2651+#define PIPE_FRAME_HIGH_MASK 0x0000ffff
2652+#define PIPE_FRAME_HIGH_SHIFT 0
2653+#define PIPEAFRAMEPIXEL 0x70044
2654+#define PIPE_FRAME_LOW_MASK 0xff000000
2655+#define PIPE_FRAME_LOW_SHIFT 24
2656+#define PIPE_PIXEL_MASK 0x00ffffff
2657+#define PIPE_PIXEL_SHIFT 0
2658+
2659+/* Cursor A & B regs */
2660+#define CURACNTR 0x70080
2661+#define CURSOR_MODE_DISABLE 0x00
2662+#define CURSOR_MODE_64_32B_AX 0x07
2663+#define CURSOR_MODE_64_ARGB_AX ((1 << 5) | CURSOR_MODE_64_32B_AX)
2664+#define MCURSOR_GAMMA_ENABLE (1 << 26)
2665+#define CURABASE 0x70084
2666+#define CURAPOS 0x70088
2667+#define CURSOR_POS_MASK 0x007FF
2668+#define CURSOR_POS_SIGN 0x8000
2669+#define CURSOR_X_SHIFT 0
2670+#define CURSOR_Y_SHIFT 16
2671+#define CURBCNTR 0x700c0
2672+#define CURBBASE 0x700c4
2673+#define CURBPOS 0x700c8
2674+
2675+/* Display A control */
2676+#define DSPACNTR 0x70180
2677+#define DISPLAY_PLANE_ENABLE (1<<31)
2678+#define DISPLAY_PLANE_DISABLE 0
2679+#define DISPPLANE_GAMMA_ENABLE (1<<30)
2680+#define DISPPLANE_GAMMA_DISABLE 0
2681+#define DISPPLANE_PIXFORMAT_MASK (0xf<<26)
2682+#define DISPPLANE_8BPP (0x2<<26)
2683+#define DISPPLANE_15_16BPP (0x4<<26)
2684+#define DISPPLANE_16BPP (0x5<<26)
2685+#define DISPPLANE_32BPP_NO_ALPHA (0x6<<26)
2686+#define DISPPLANE_32BPP (0x7<<26)
2687+#define DISPPLANE_STEREO_ENABLE (1<<25)
2688+#define DISPPLANE_STEREO_DISABLE 0
2689+#define DISPPLANE_SEL_PIPE_MASK (1<<24)
2690+#define DISPPLANE_SEL_PIPE_A 0
2691+#define DISPPLANE_SEL_PIPE_B (1<<24)
2692+#define DISPPLANE_SRC_KEY_ENABLE (1<<22)
2693+#define DISPPLANE_SRC_KEY_DISABLE 0
2694+#define DISPPLANE_LINE_DOUBLE (1<<20)
2695+#define DISPPLANE_NO_LINE_DOUBLE 0
2696+#define DISPPLANE_STEREO_POLARITY_FIRST 0
2697+#define DISPPLANE_STEREO_POLARITY_SECOND (1<<18)
2698+#define DSPAADDR 0x70184
2699+#define DSPASTRIDE 0x70188
2700+#define DSPAPOS 0x7018C /* reserved */
2701+#define DSPASIZE 0x70190
2702+#define DSPASURF 0x7019C /* 965+ only */
2703+#define DSPATILEOFF 0x701A4 /* 965+ only */
2704+
2705+/* VBIOS flags */
2706+#define SWF00 0x71410
2707+#define SWF01 0x71414
2708+#define SWF02 0x71418
2709+#define SWF03 0x7141c
2710+#define SWF04 0x71420
2711+#define SWF05 0x71424
2712+#define SWF06 0x71428
2713+#define SWF10 0x70410
2714+#define SWF11 0x70414
2715+#define SWF14 0x71420
2716+#define SWF30 0x72414
2717+#define SWF31 0x72418
2718+#define SWF32 0x7241c
2719+
2720+/* Pipe B */
2721+#define PIPEBDSL 0x71000
2722+#define PIPEBCONF 0x71008
2723+#define PIPEBSTAT 0x71024
2724+#define PIPEBFRAMEHIGH 0x71040
2725+#define PIPEBFRAMEPIXEL 0x71044
2726+
2727+/* Display B control */
2728+#define DSPBCNTR 0x71180
2729+#define DISPPLANE_ALPHA_TRANS_ENABLE (1<<15)
2730+#define DISPPLANE_ALPHA_TRANS_DISABLE 0
2731+#define DISPPLANE_SPRITE_ABOVE_DISPLAY 0
2732+#define DISPPLANE_SPRITE_ABOVE_OVERLAY (1)
2733+#define DSPBADDR 0x71184
2734+#define DSPBSTRIDE 0x71188
2735+#define DSPBPOS 0x7118C
2736+#define DSPBSIZE 0x71190
2737+#define DSPBSURF 0x7119C
2738+#define DSPBTILEOFF 0x711A4
2739+
2740+/* VBIOS regs */
2741+#define VGACNTRL 0x71400
2742+# define VGA_DISP_DISABLE (1 << 31)
2743+# define VGA_2X_MODE (1 << 30)
2744+# define VGA_PIPE_B_SELECT (1 << 29)
2745+
2746+#endif /* _I915_REG_H_ */
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0005-i915-Add-support-for-MSI-and-interrupt-mitigation.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0005-i915-Add-support-for-MSI-and-interrupt-mitigation.patch
new file mode 100644
index 0000000000..9337475c31
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0005-i915-Add-support-for-MSI-and-interrupt-mitigation.patch
@@ -0,0 +1,424 @@
1commit 4f99970852559935b27bc634318f34c18c5fd143
2Author: Eric Anholt <eric@anholt.net>
3Date: Tue Jul 29 12:10:39 2008 -0700
4
5 i915: Add support for MSI and interrupt mitigation.
6
7 Previous attempts at interrupt mitigation had been foiled by i915_wait_irq's
8 failure to update the sarea seqno value when the status page indicated that
9 the seqno had already been passed. MSI support has been seen to cut CPU
10 costs by up to 40% in some workloads by avoiding other expensive interrupt
11 handlers for frequent graphics interrupts.
12
13 Signed-off-by: Eric Anholt <eric@anholt.net>
14 Signed-off-by: Dave Airlie <airlied@redhat.com>
15
16diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
17index 53f0e5a..61ed515 100644
18--- a/drivers/gpu/drm/drm_irq.c
19+++ b/drivers/gpu/drm/drm_irq.c
20@@ -63,7 +63,7 @@ int drm_irq_by_busid(struct drm_device *dev, void *data,
21 p->devnum != PCI_SLOT(dev->pdev->devfn) || p->funcnum != PCI_FUNC(dev->pdev->devfn))
22 return -EINVAL;
23
24- p->irq = dev->irq;
25+ p->irq = dev->pdev->irq;
26
27 DRM_DEBUG("%d:%d:%d => IRQ %d\n", p->busnum, p->devnum, p->funcnum,
28 p->irq);
29@@ -89,7 +89,7 @@ static int drm_irq_install(struct drm_device * dev)
30 if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
31 return -EINVAL;
32
33- if (dev->irq == 0)
34+ if (dev->pdev->irq == 0)
35 return -EINVAL;
36
37 mutex_lock(&dev->struct_mutex);
38@@ -107,7 +107,7 @@ static int drm_irq_install(struct drm_device * dev)
39 dev->irq_enabled = 1;
40 mutex_unlock(&dev->struct_mutex);
41
42- DRM_DEBUG("irq=%d\n", dev->irq);
43+ DRM_DEBUG("irq=%d\n", dev->pdev->irq);
44
45 if (drm_core_check_feature(dev, DRIVER_IRQ_VBL)) {
46 init_waitqueue_head(&dev->vbl_queue);
47@@ -127,8 +127,12 @@ static int drm_irq_install(struct drm_device * dev)
48 if (drm_core_check_feature(dev, DRIVER_IRQ_SHARED))
49 sh_flags = IRQF_SHARED;
50
51- ret = request_irq(dev->irq, dev->driver->irq_handler,
52+ ret = request_irq(dev->pdev->irq, dev->driver->irq_handler,
53 sh_flags, dev->devname, dev);
54+ /* Expose the device irq number to drivers that want to export it for
55+ * whatever reason.
56+ */
57+ dev->irq = dev->pdev->irq;
58 if (ret < 0) {
59 mutex_lock(&dev->struct_mutex);
60 dev->irq_enabled = 0;
61@@ -164,11 +168,11 @@ int drm_irq_uninstall(struct drm_device * dev)
62 if (!irq_enabled)
63 return -EINVAL;
64
65- DRM_DEBUG("irq=%d\n", dev->irq);
66+ DRM_DEBUG("irq=%d\n", dev->pdev->irq);
67
68 dev->driver->irq_uninstall(dev);
69
70- free_irq(dev->irq, dev);
71+ free_irq(dev->pdev->irq, dev);
72
73 dev->locked_tasklet_func = NULL;
74
75@@ -201,7 +205,7 @@ int drm_control(struct drm_device *dev, void *data,
76 if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
77 return 0;
78 if (dev->if_version < DRM_IF_VERSION(1, 2) &&
79- ctl->irq != dev->irq)
80+ ctl->irq != dev->pdev->irq)
81 return -EINVAL;
82 return drm_irq_install(dev);
83 case DRM_UNINST_HANDLER:
84@@ -239,7 +243,7 @@ int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_pr
85 int ret = 0;
86 unsigned int flags, seq;
87
88- if ((!dev->irq) || (!dev->irq_enabled))
89+ if ((!dev->pdev->irq) || (!dev->irq_enabled))
90 return -EINVAL;
91
92 if (vblwait->request.type &
93diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
94index 7be580b..10bfb0c 100644
95--- a/drivers/gpu/drm/i915/i915_dma.c
96+++ b/drivers/gpu/drm/i915/i915_dma.c
97@@ -84,7 +84,7 @@ static int i915_dma_cleanup(struct drm_device * dev)
98 * may not have been called from userspace and after dev_private
99 * is freed, it's too late.
100 */
101- if (dev->irq)
102+ if (dev->irq_enabled)
103 drm_irq_uninstall(dev);
104
105 if (dev_priv->ring.virtual_start) {
106@@ -644,7 +644,7 @@ static int i915_getparam(struct drm_device *dev, void *data,
107
108 switch (param->param) {
109 case I915_PARAM_IRQ_ACTIVE:
110- value = dev->irq ? 1 : 0;
111+ value = dev->irq_enabled;
112 break;
113 case I915_PARAM_ALLOW_BATCHBUFFER:
114 value = dev_priv->allow_batchbuffer ? 1 : 0;
115@@ -763,6 +763,20 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
116 ret = drm_addmap(dev, base, size, _DRM_REGISTERS,
117 _DRM_KERNEL | _DRM_DRIVER,
118 &dev_priv->mmio_map);
119+
120+
121+ /* On the 945G/GM, the chipset reports the MSI capability on the
122+ * integrated graphics even though the support isn't actually there
123+ * according to the published specs. It doesn't appear to function
124+ * correctly in testing on 945G.
125+ * This may be a side effect of MSI having been made available for PEG
126+ * and the registers being closely associated.
127+ */
128+ if (!IS_I945G(dev) && !IS_I945GM(dev))
129+ pci_enable_msi(dev->pdev);
130+
131+ spin_lock_init(&dev_priv->user_irq_lock);
132+
133 return ret;
134 }
135
136@@ -770,6 +784,9 @@ int i915_driver_unload(struct drm_device *dev)
137 {
138 struct drm_i915_private *dev_priv = dev->dev_private;
139
140+ if (dev->pdev->msi_enabled)
141+ pci_disable_msi(dev->pdev);
142+
143 if (dev_priv->mmio_map)
144 drm_rmmap(dev, dev_priv->mmio_map);
145
146diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
147index afb51a3..8daf0d8 100644
148--- a/drivers/gpu/drm/i915/i915_drv.h
149+++ b/drivers/gpu/drm/i915/i915_drv.h
150@@ -105,6 +105,12 @@ typedef struct drm_i915_private {
151 wait_queue_head_t irq_queue;
152 atomic_t irq_received;
153 atomic_t irq_emitted;
154+ /** Protects user_irq_refcount and irq_mask_reg */
155+ spinlock_t user_irq_lock;
156+ /** Refcount for i915_user_irq_get() versus i915_user_irq_put(). */
157+ int user_irq_refcount;
158+ /** Cached value of IMR to avoid reads in updating the bitfield */
159+ u32 irq_mask_reg;
160
161 int tex_lru_log_granularity;
162 int allow_batchbuffer;
163diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
164index 4a2de78..24d11ed 100644
165--- a/drivers/gpu/drm/i915/i915_irq.c
166+++ b/drivers/gpu/drm/i915/i915_irq.c
167@@ -33,6 +33,31 @@
168
169 #define MAX_NOPID ((u32)~0)
170
171+/** These are the interrupts used by the driver */
172+#define I915_INTERRUPT_ENABLE_MASK (I915_USER_INTERRUPT | \
173+ I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT | \
174+ I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT)
175+
176+static inline void
177+i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask)
178+{
179+ if ((dev_priv->irq_mask_reg & mask) != 0) {
180+ dev_priv->irq_mask_reg &= ~mask;
181+ I915_WRITE(IMR, dev_priv->irq_mask_reg);
182+ (void) I915_READ(IMR);
183+ }
184+}
185+
186+static inline void
187+i915_disable_irq(drm_i915_private_t *dev_priv, u32 mask)
188+{
189+ if ((dev_priv->irq_mask_reg & mask) != mask) {
190+ dev_priv->irq_mask_reg |= mask;
191+ I915_WRITE(IMR, dev_priv->irq_mask_reg);
192+ (void) I915_READ(IMR);
193+ }
194+}
195+
196 /**
197 * Emit blits for scheduled buffer swaps.
198 *
199@@ -229,46 +254,50 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
200 {
201 struct drm_device *dev = (struct drm_device *) arg;
202 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
203- u16 temp;
204 u32 pipea_stats, pipeb_stats;
205+ u32 iir;
206
207 pipea_stats = I915_READ(PIPEASTAT);
208 pipeb_stats = I915_READ(PIPEBSTAT);
209
210- temp = I915_READ16(IIR);
211-
212- temp &= (I915_USER_INTERRUPT |
213- I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT |
214- I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT);
215+ if (dev->pdev->msi_enabled)
216+ I915_WRITE(IMR, ~0);
217+ iir = I915_READ(IIR);
218
219- DRM_DEBUG("%s flag=%08x\n", __FUNCTION__, temp);
220+ DRM_DEBUG("iir=%08x\n", iir);
221
222- if (temp == 0)
223+ if (iir == 0) {
224+ if (dev->pdev->msi_enabled) {
225+ I915_WRITE(IMR, dev_priv->irq_mask_reg);
226+ (void) I915_READ(IMR);
227+ }
228 return IRQ_NONE;
229+ }
230
231- I915_WRITE16(IIR, temp);
232- (void) I915_READ16(IIR);
233- DRM_READMEMORYBARRIER();
234+ I915_WRITE(IIR, iir);
235+ if (dev->pdev->msi_enabled)
236+ I915_WRITE(IMR, dev_priv->irq_mask_reg);
237+ (void) I915_READ(IIR); /* Flush posted writes */
238
239 dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
240
241- if (temp & I915_USER_INTERRUPT)
242+ if (iir & I915_USER_INTERRUPT)
243 DRM_WAKEUP(&dev_priv->irq_queue);
244
245- if (temp & (I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT |
246- I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT)) {
247+ if (iir & (I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT |
248+ I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT)) {
249 int vblank_pipe = dev_priv->vblank_pipe;
250
251 if ((vblank_pipe &
252 (DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B))
253 == (DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B)) {
254- if (temp & I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT)
255+ if (iir & I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT)
256 atomic_inc(&dev->vbl_received);
257- if (temp & I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT)
258+ if (iir & I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT)
259 atomic_inc(&dev->vbl_received2);
260- } else if (((temp & I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT) &&
261+ } else if (((iir & I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT) &&
262 (vblank_pipe & DRM_I915_VBLANK_PIPE_A)) ||
263- ((temp & I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT) &&
264+ ((iir & I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT) &&
265 (vblank_pipe & DRM_I915_VBLANK_PIPE_B)))
266 atomic_inc(&dev->vbl_received);
267
268@@ -314,6 +343,27 @@ static int i915_emit_irq(struct drm_device * dev)
269 return dev_priv->counter;
270 }
271
272+static void i915_user_irq_get(struct drm_device *dev)
273+{
274+ drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
275+
276+ spin_lock(&dev_priv->user_irq_lock);
277+ if (dev->irq_enabled && (++dev_priv->user_irq_refcount == 1))
278+ i915_enable_irq(dev_priv, I915_USER_INTERRUPT);
279+ spin_unlock(&dev_priv->user_irq_lock);
280+}
281+
282+static void i915_user_irq_put(struct drm_device *dev)
283+{
284+ drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
285+
286+ spin_lock(&dev_priv->user_irq_lock);
287+ BUG_ON(dev->irq_enabled && dev_priv->user_irq_refcount <= 0);
288+ if (dev->irq_enabled && (--dev_priv->user_irq_refcount == 0))
289+ i915_disable_irq(dev_priv, I915_USER_INTERRUPT);
290+ spin_unlock(&dev_priv->user_irq_lock);
291+}
292+
293 static int i915_wait_irq(struct drm_device * dev, int irq_nr)
294 {
295 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
296@@ -322,13 +372,17 @@ static int i915_wait_irq(struct drm_device * dev, int irq_nr)
297 DRM_DEBUG("irq_nr=%d breadcrumb=%d\n", irq_nr,
298 READ_BREADCRUMB(dev_priv));
299
300- if (READ_BREADCRUMB(dev_priv) >= irq_nr)
301+ if (READ_BREADCRUMB(dev_priv) >= irq_nr) {
302+ dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
303 return 0;
304+ }
305
306 dev_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT;
307
308+ i915_user_irq_get(dev);
309 DRM_WAIT_ON(ret, dev_priv->irq_queue, 3 * DRM_HZ,
310 READ_BREADCRUMB(dev_priv) >= irq_nr);
311+ i915_user_irq_put(dev);
312
313 if (ret == -EBUSY) {
314 DRM_ERROR("EBUSY -- rec: %d emitted: %d\n",
315@@ -413,20 +467,6 @@ int i915_irq_wait(struct drm_device *dev, void *data,
316 return i915_wait_irq(dev, irqwait->irq_seq);
317 }
318
319-static void i915_enable_interrupt (struct drm_device *dev)
320-{
321- drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
322- u16 flag;
323-
324- flag = 0;
325- if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_A)
326- flag |= I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT;
327- if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_B)
328- flag |= I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
329-
330- I915_WRITE16(IER, I915_USER_INTERRUPT | flag);
331-}
332-
333 /* Set the vblank monitor pipe
334 */
335 int i915_vblank_pipe_set(struct drm_device *dev, void *data,
336@@ -434,6 +474,7 @@ int i915_vblank_pipe_set(struct drm_device *dev, void *data,
337 {
338 drm_i915_private_t *dev_priv = dev->dev_private;
339 drm_i915_vblank_pipe_t *pipe = data;
340+ u32 enable_mask = 0, disable_mask = 0;
341
342 if (!dev_priv) {
343 DRM_ERROR("called with no initialization\n");
344@@ -445,9 +486,20 @@ int i915_vblank_pipe_set(struct drm_device *dev, void *data,
345 return -EINVAL;
346 }
347
348- dev_priv->vblank_pipe = pipe->pipe;
349+ if (pipe->pipe & DRM_I915_VBLANK_PIPE_A)
350+ enable_mask |= I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT;
351+ else
352+ disable_mask |= I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT;
353+
354+ if (pipe->pipe & DRM_I915_VBLANK_PIPE_B)
355+ enable_mask |= I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
356+ else
357+ disable_mask |= I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
358
359- i915_enable_interrupt (dev);
360+ i915_enable_irq(dev_priv, enable_mask);
361+ i915_disable_irq(dev_priv, disable_mask);
362+
363+ dev_priv->vblank_pipe = pipe->pipe;
364
365 return 0;
366 }
367@@ -464,7 +516,7 @@ int i915_vblank_pipe_get(struct drm_device *dev, void *data,
368 return -EINVAL;
369 }
370
371- flag = I915_READ(IER);
372+ flag = I915_READ(IMR);
373 pipe->pipe = 0;
374 if (flag & I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT)
375 pipe->pipe |= DRM_I915_VBLANK_PIPE_A;
376@@ -586,9 +638,9 @@ void i915_driver_irq_preinstall(struct drm_device * dev)
377 {
378 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
379
380- I915_WRITE16(HWSTAM, 0xfffe);
381- I915_WRITE16(IMR, 0x0);
382- I915_WRITE16(IER, 0x0);
383+ I915_WRITE(HWSTAM, 0xfffe);
384+ I915_WRITE(IMR, 0x0);
385+ I915_WRITE(IER, 0x0);
386 }
387
388 void i915_driver_irq_postinstall(struct drm_device * dev)
389@@ -601,7 +653,18 @@ void i915_driver_irq_postinstall(struct drm_device * dev)
390
391 if (!dev_priv->vblank_pipe)
392 dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A;
393- i915_enable_interrupt(dev);
394+
395+ /* Set initial unmasked IRQs to just the selected vblank pipes. */
396+ dev_priv->irq_mask_reg = ~0;
397+ if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_A)
398+ dev_priv->irq_mask_reg &= ~I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT;
399+ if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_B)
400+ dev_priv->irq_mask_reg &= ~I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
401+
402+ I915_WRITE(IMR, dev_priv->irq_mask_reg);
403+ I915_WRITE(IER, I915_INTERRUPT_ENABLE_MASK);
404+ (void) I915_READ(IER);
405+
406 DRM_INIT_WAITQUEUE(&dev_priv->irq_queue);
407 }
408
409@@ -613,10 +676,10 @@ void i915_driver_irq_uninstall(struct drm_device * dev)
410 if (!dev_priv)
411 return;
412
413- I915_WRITE16(HWSTAM, 0xffff);
414- I915_WRITE16(IMR, 0xffff);
415- I915_WRITE16(IER, 0x0);
416+ I915_WRITE(HWSTAM, 0xffff);
417+ I915_WRITE(IMR, 0xffff);
418+ I915_WRITE(IER, 0x0);
419
420- temp = I915_READ16(IIR);
421- I915_WRITE16(IIR, temp);
422+ temp = I915_READ(IIR);
423+ I915_WRITE(IIR, temp);
424 }
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0006-i915-Track-progress-inside-of-batchbuffers-for-dete.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0006-i915-Track-progress-inside-of-batchbuffers-for-dete.patch
new file mode 100644
index 0000000000..8736250f00
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0006-i915-Track-progress-inside-of-batchbuffers-for-dete.patch
@@ -0,0 +1,46 @@
1commit 1236e8610ab9c6f9f8297e60530bedb2640c7224
2Author: Keith Packard <keithp@keithp.com>
3Date: Wed Jul 30 12:21:20 2008 -0700
4
5 i915: Track progress inside of batchbuffers for determining wedgedness.
6
7 This avoids early termination for long-running commands.
8
9 Signed-off-by: Eric Anholt <eric@anholt.net>
10 Signed-off-by: Dave Airlie <airlied@redhat.com>
11
12diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
13index 10bfb0c..4c72a01 100644
14--- a/drivers/gpu/drm/i915/i915_dma.c
15+++ b/drivers/gpu/drm/i915/i915_dma.c
16@@ -40,11 +40,15 @@ int i915_wait_ring(struct drm_device * dev, int n, const char *caller)
17 {
18 drm_i915_private_t *dev_priv = dev->dev_private;
19 drm_i915_ring_buffer_t *ring = &(dev_priv->ring);
20+ u32 acthd_reg = IS_I965G(dev) ? ACTHD_I965 : ACTHD;
21+ u32 last_acthd = I915_READ(acthd_reg);
22+ u32 acthd;
23 u32 last_head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
24 int i;
25
26- for (i = 0; i < 10000; i++) {
27+ for (i = 0; i < 100000; i++) {
28 ring->head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
29+ acthd = I915_READ(acthd_reg);
30 ring->space = ring->head - (ring->tail + 8);
31 if (ring->space < 0)
32 ring->space += ring->Size;
33@@ -55,8 +59,13 @@ int i915_wait_ring(struct drm_device * dev, int n, const char *caller)
34
35 if (ring->head != last_head)
36 i = 0;
37+ if (acthd != last_acthd)
38+ i = 0;
39
40 last_head = ring->head;
41+ last_acthd = acthd;
42+ msleep_interruptible(10);
43+
44 }
45
46 return -EBUSY;
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0007-i915-Initialize-hardware-status-page-at-device-load.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0007-i915-Initialize-hardware-status-page-at-device-load.patch
new file mode 100644
index 0000000000..79f068f422
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0007-i915-Initialize-hardware-status-page-at-device-load.patch
@@ -0,0 +1,137 @@
1commit 75fed4ae8454aa975c274b2585ec2287dd15773d
2Author: Keith Packard <keithp@keithp.com>
3Date: Wed Jul 30 13:03:43 2008 -0700
4
5 i915: Initialize hardware status page at device load when possible.
6
7 Some chips were unstable with repeated setup/teardown of the hardware status
8 page.
9
10 Signed-off-by: Eric Anholt <eric@anholt.net>
11 Signed-off-by: Dave Airlie <airlied@redhat.com>
12
13diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
14index 4c72a01..b3c4ac9 100644
15--- a/drivers/gpu/drm/i915/i915_dma.c
16+++ b/drivers/gpu/drm/i915/i915_dma.c
17@@ -71,6 +71,52 @@ int i915_wait_ring(struct drm_device * dev, int n, const char *caller)
18 return -EBUSY;
19 }
20
21+/**
22+ * Sets up the hardware status page for devices that need a physical address
23+ * in the register.
24+ */
25+int i915_init_phys_hws(struct drm_device *dev)
26+{
27+ drm_i915_private_t *dev_priv = dev->dev_private;
28+ /* Program Hardware Status Page */
29+ dev_priv->status_page_dmah =
30+ drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 0xffffffff);
31+
32+ if (!dev_priv->status_page_dmah) {
33+ DRM_ERROR("Can not allocate hardware status page\n");
34+ return -ENOMEM;
35+ }
36+ dev_priv->hw_status_page = dev_priv->status_page_dmah->vaddr;
37+ dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr;
38+
39+ memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
40+
41+ I915_WRITE(HWS_PGA, dev_priv->dma_status_page);
42+ DRM_DEBUG("Enabled hardware status page\n");
43+ return 0;
44+}
45+
46+/**
47+ * Frees the hardware status page, whether it's a physical address or a virtual
48+ * address set up by the X Server.
49+ */
50+void i915_free_hws(struct drm_device *dev)
51+{
52+ drm_i915_private_t *dev_priv = dev->dev_private;
53+ if (dev_priv->status_page_dmah) {
54+ drm_pci_free(dev, dev_priv->status_page_dmah);
55+ dev_priv->status_page_dmah = NULL;
56+ }
57+
58+ if (dev_priv->status_gfx_addr) {
59+ dev_priv->status_gfx_addr = 0;
60+ drm_core_ioremapfree(&dev_priv->hws_map, dev);
61+ }
62+
63+ /* Need to rewrite hardware status page */
64+ I915_WRITE(HWS_PGA, 0x1ffff000);
65+}
66+
67 void i915_kernel_lost_context(struct drm_device * dev)
68 {
69 drm_i915_private_t *dev_priv = dev->dev_private;
70@@ -103,18 +149,9 @@ static int i915_dma_cleanup(struct drm_device * dev)
71 dev_priv->ring.map.size = 0;
72 }
73
74- if (dev_priv->status_page_dmah) {
75- drm_pci_free(dev, dev_priv->status_page_dmah);
76- dev_priv->status_page_dmah = NULL;
77- /* Need to rewrite hardware status page */
78- I915_WRITE(HWS_PGA, 0x1ffff000);
79- }
80-
81- if (dev_priv->status_gfx_addr) {
82- dev_priv->status_gfx_addr = 0;
83- drm_core_ioremapfree(&dev_priv->hws_map, dev);
84- I915_WRITE(HWS_PGA, 0x1ffff000);
85- }
86+ /* Clear the HWS virtual address at teardown */
87+ if (I915_NEED_GFX_HWS(dev))
88+ i915_free_hws(dev);
89
90 return 0;
91 }
92@@ -165,23 +202,6 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
93 */
94 dev_priv->allow_batchbuffer = 1;
95
96- /* Program Hardware Status Page */
97- if (!I915_NEED_GFX_HWS(dev)) {
98- dev_priv->status_page_dmah =
99- drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 0xffffffff);
100-
101- if (!dev_priv->status_page_dmah) {
102- i915_dma_cleanup(dev);
103- DRM_ERROR("Can not allocate hardware status page\n");
104- return -ENOMEM;
105- }
106- dev_priv->hw_status_page = dev_priv->status_page_dmah->vaddr;
107- dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr;
108-
109- memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
110- I915_WRITE(HWS_PGA, dev_priv->dma_status_page);
111- }
112- DRM_DEBUG("Enabled hardware status page\n");
113 return 0;
114 }
115
116@@ -773,6 +793,12 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
117 _DRM_KERNEL | _DRM_DRIVER,
118 &dev_priv->mmio_map);
119
120+ /* Init HWS */
121+ if (!I915_NEED_GFX_HWS(dev)) {
122+ ret = i915_init_phys_hws(dev);
123+ if (ret != 0)
124+ return ret;
125+ }
126
127 /* On the 945G/GM, the chipset reports the MSI capability on the
128 * integrated graphics even though the support isn't actually there
129@@ -796,6 +822,8 @@ int i915_driver_unload(struct drm_device *dev)
130 if (dev->pdev->msi_enabled)
131 pci_disable_msi(dev->pdev);
132
133+ i915_free_hws(dev);
134+
135 if (dev_priv->mmio_map)
136 drm_rmmap(dev, dev_priv->mmio_map);
137
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0008-Add-Intel-ACPI-IGD-OpRegion-support.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0008-Add-Intel-ACPI-IGD-OpRegion-support.patch
new file mode 100644
index 0000000000..afa6f96345
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0008-Add-Intel-ACPI-IGD-OpRegion-support.patch
@@ -0,0 +1,572 @@
1commit 91c2ebb8e78aa64f4807399b506ec0090ae5f3d6
2Author: Matthew Garrett <mjg59@srcf.ucam.org>
3Date: Tue Aug 5 19:37:25 2008 +0100
4
5 Add Intel ACPI IGD OpRegion support
6
7 This adds the support necessary for allowing ACPI backlight control to
8 work on some newer Intel-based graphics systems. Tested on Thinkpad T61
9 and HP 2510p hardware.
10
11 Signed-off-by: Matthew Garrett <mjg@redhat.com>
12 Signed-off-by: Dave Airlie <airlied@linux.ie>
13
14diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
15index a9e6046..b032808 100644
16--- a/drivers/gpu/drm/i915/Makefile
17+++ b/drivers/gpu/drm/i915/Makefile
18@@ -3,7 +3,7 @@
19 # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
20
21 ccflags-y := -Iinclude/drm
22-i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o
23+i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o i915_opregion.o
24
25 i915-$(CONFIG_COMPAT) += i915_ioc32.o
26
27diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
28index b3c4ac9..cead62f 100644
29--- a/drivers/gpu/drm/i915/i915_dma.c
30+++ b/drivers/gpu/drm/i915/i915_dma.c
31@@ -810,6 +810,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
32 if (!IS_I945G(dev) && !IS_I945GM(dev))
33 pci_enable_msi(dev->pdev);
34
35+ intel_opregion_init(dev);
36+
37 spin_lock_init(&dev_priv->user_irq_lock);
38
39 return ret;
40@@ -827,6 +829,8 @@ int i915_driver_unload(struct drm_device *dev)
41 if (dev_priv->mmio_map)
42 drm_rmmap(dev, dev_priv->mmio_map);
43
44+ intel_opregion_free(dev);
45+
46 drm_free(dev->dev_private, sizeof(drm_i915_private_t),
47 DRM_MEM_DRIVER);
48
49diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
50index 6c99aab..d95eca2 100644
51--- a/drivers/gpu/drm/i915/i915_drv.c
52+++ b/drivers/gpu/drm/i915/i915_drv.c
53@@ -371,6 +371,8 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state)
54
55 i915_save_vga(dev);
56
57+ intel_opregion_free(dev);
58+
59 if (state.event == PM_EVENT_SUSPEND) {
60 /* Shut down the device */
61 pci_disable_device(dev->pdev);
62@@ -532,6 +534,8 @@ static int i915_resume(struct drm_device *dev)
63
64 i915_restore_vga(dev);
65
66+ intel_opregion_init(dev);
67+
68 return 0;
69 }
70
71diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
72index 8daf0d8..e4bd01c 100644
73--- a/drivers/gpu/drm/i915/i915_drv.h
74+++ b/drivers/gpu/drm/i915/i915_drv.h
75@@ -82,6 +82,14 @@ typedef struct _drm_i915_vbl_swap {
76 unsigned int sequence;
77 } drm_i915_vbl_swap_t;
78
79+struct intel_opregion {
80+ struct opregion_header *header;
81+ struct opregion_acpi *acpi;
82+ struct opregion_swsci *swsci;
83+ struct opregion_asle *asle;
84+ int enabled;
85+};
86+
87 typedef struct drm_i915_private {
88 drm_local_map_t *sarea;
89 drm_local_map_t *mmio_map;
90@@ -122,6 +130,8 @@ typedef struct drm_i915_private {
91 drm_i915_vbl_swap_t vbl_swaps;
92 unsigned int swaps_pending;
93
94+ struct intel_opregion opregion;
95+
96 /* Register state */
97 u8 saveLBB;
98 u32 saveDSPACNTR;
99@@ -244,6 +254,7 @@ extern int i915_vblank_pipe_get(struct drm_device *dev, void *data,
100 struct drm_file *file_priv);
101 extern int i915_vblank_swap(struct drm_device *dev, void *data,
102 struct drm_file *file_priv);
103+extern void i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask);
104
105 /* i915_mem.c */
106 extern int i915_mem_alloc(struct drm_device *dev, void *data,
107@@ -258,6 +269,12 @@ extern void i915_mem_takedown(struct mem_block **heap);
108 extern void i915_mem_release(struct drm_device * dev,
109 struct drm_file *file_priv, struct mem_block *heap);
110
111+/* i915_opregion.c */
112+extern int intel_opregion_init(struct drm_device *dev);
113+extern void intel_opregion_free(struct drm_device *dev);
114+extern void opregion_asle_intr(struct drm_device *dev);
115+extern void opregion_enable_asle(struct drm_device *dev);
116+
117 #define I915_READ(reg) DRM_READ32(dev_priv->mmio_map, (reg))
118 #define I915_WRITE(reg,val) DRM_WRITE32(dev_priv->mmio_map, (reg), (val))
119 #define I915_READ16(reg) DRM_READ16(dev_priv->mmio_map, (reg))
120diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
121index 24d11ed..ae7d3a8 100644
122--- a/drivers/gpu/drm/i915/i915_irq.c
123+++ b/drivers/gpu/drm/i915/i915_irq.c
124@@ -36,9 +36,11 @@
125 /** These are the interrupts used by the driver */
126 #define I915_INTERRUPT_ENABLE_MASK (I915_USER_INTERRUPT | \
127 I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT | \
128- I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT)
129+ I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT | \
130+ I915_ASLE_INTERRUPT | \
131+ I915_DISPLAY_PIPE_B_EVENT_INTERRUPT)
132
133-static inline void
134+void
135 i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask)
136 {
137 if ((dev_priv->irq_mask_reg & mask) != 0) {
138@@ -274,6 +276,9 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
139 return IRQ_NONE;
140 }
141
142+ I915_WRITE(PIPEASTAT, pipea_stats);
143+ I915_WRITE(PIPEBSTAT, pipeb_stats);
144+
145 I915_WRITE(IIR, iir);
146 if (dev->pdev->msi_enabled)
147 I915_WRITE(IMR, dev_priv->irq_mask_reg);
148@@ -306,14 +311,14 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
149
150 if (dev_priv->swaps_pending > 0)
151 drm_locked_tasklet(dev, i915_vblank_tasklet);
152- I915_WRITE(PIPEASTAT,
153- pipea_stats|I915_VBLANK_INTERRUPT_ENABLE|
154- PIPE_VBLANK_INTERRUPT_STATUS);
155- I915_WRITE(PIPEBSTAT,
156- pipeb_stats|I915_VBLANK_INTERRUPT_ENABLE|
157- PIPE_VBLANK_INTERRUPT_STATUS);
158 }
159
160+ if (iir & I915_ASLE_INTERRUPT)
161+ opregion_asle_intr(dev);
162+
163+ if (iir & I915_DISPLAY_PIPE_B_EVENT_INTERRUPT)
164+ opregion_asle_intr(dev);
165+
166 return IRQ_HANDLED;
167 }
168
169@@ -661,10 +666,14 @@ void i915_driver_irq_postinstall(struct drm_device * dev)
170 if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_B)
171 dev_priv->irq_mask_reg &= ~I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
172
173+ dev_priv->irq_mask_reg &= I915_INTERRUPT_ENABLE_MASK;
174+
175 I915_WRITE(IMR, dev_priv->irq_mask_reg);
176 I915_WRITE(IER, I915_INTERRUPT_ENABLE_MASK);
177 (void) I915_READ(IER);
178
179+ opregion_enable_asle(dev);
180+
181 DRM_INIT_WAITQUEUE(&dev_priv->irq_queue);
182 }
183
184diff --git a/drivers/gpu/drm/i915/i915_opregion.c b/drivers/gpu/drm/i915/i915_opregion.c
185new file mode 100644
186index 0000000..1787a0c
187--- /dev/null
188+++ b/drivers/gpu/drm/i915/i915_opregion.c
189@@ -0,0 +1,371 @@
190+/*
191+ * Copyright 2008 Intel Corporation <hong.liu@intel.com>
192+ * Copyright 2008 Red Hat <mjg@redhat.com>
193+ *
194+ * Permission is hereby granted, free of charge, to any person obtaining
195+ * a copy of this software and associated documentation files (the
196+ * "Software"), to deal in the Software without restriction, including
197+ * without limitation the rights to use, copy, modify, merge, publish,
198+ * distribute, sub license, and/or sell copies of the Software, and to
199+ * permit persons to whom the Software is furnished to do so, subject to
200+ * the following conditions:
201+ *
202+ * The above copyright notice and this permission notice (including the
203+ * next paragraph) shall be included in all copies or substantial
204+ * portions of the Software.
205+ *
206+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
207+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
208+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
209+ * NON-INFRINGEMENT. IN NO EVENT SHALL INTEL AND/OR ITS SUPPLIERS BE
210+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
211+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
212+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
213+ * SOFTWARE.
214+ *
215+ */
216+
217+#include <linux/acpi.h>
218+
219+#include "drmP.h"
220+#include "i915_drm.h"
221+#include "i915_drv.h"
222+
223+#define PCI_ASLE 0xe4
224+#define PCI_LBPC 0xf4
225+#define PCI_ASLS 0xfc
226+
227+#define OPREGION_SZ (8*1024)
228+#define OPREGION_HEADER_OFFSET 0
229+#define OPREGION_ACPI_OFFSET 0x100
230+#define OPREGION_SWSCI_OFFSET 0x200
231+#define OPREGION_ASLE_OFFSET 0x300
232+#define OPREGION_VBT_OFFSET 0x1000
233+
234+#define OPREGION_SIGNATURE "IntelGraphicsMem"
235+#define MBOX_ACPI (1<<0)
236+#define MBOX_SWSCI (1<<1)
237+#define MBOX_ASLE (1<<2)
238+
239+struct opregion_header {
240+ u8 signature[16];
241+ u32 size;
242+ u32 opregion_ver;
243+ u8 bios_ver[32];
244+ u8 vbios_ver[16];
245+ u8 driver_ver[16];
246+ u32 mboxes;
247+ u8 reserved[164];
248+} __attribute__((packed));
249+
250+/* OpRegion mailbox #1: public ACPI methods */
251+struct opregion_acpi {
252+ u32 drdy; /* driver readiness */
253+ u32 csts; /* notification status */
254+ u32 cevt; /* current event */
255+ u8 rsvd1[20];
256+ u32 didl[8]; /* supported display devices ID list */
257+ u32 cpdl[8]; /* currently presented display list */
258+ u32 cadl[8]; /* currently active display list */
259+ u32 nadl[8]; /* next active devices list */
260+ u32 aslp; /* ASL sleep time-out */
261+ u32 tidx; /* toggle table index */
262+ u32 chpd; /* current hotplug enable indicator */
263+ u32 clid; /* current lid state*/
264+ u32 cdck; /* current docking state */
265+ u32 sxsw; /* Sx state resume */
266+ u32 evts; /* ASL supported events */
267+ u32 cnot; /* current OS notification */
268+ u32 nrdy; /* driver status */
269+ u8 rsvd2[60];
270+} __attribute__((packed));
271+
272+/* OpRegion mailbox #2: SWSCI */
273+struct opregion_swsci {
274+ u32 scic; /* SWSCI command|status|data */
275+ u32 parm; /* command parameters */
276+ u32 dslp; /* driver sleep time-out */
277+ u8 rsvd[244];
278+} __attribute__((packed));
279+
280+/* OpRegion mailbox #3: ASLE */
281+struct opregion_asle {
282+ u32 ardy; /* driver readiness */
283+ u32 aslc; /* ASLE interrupt command */
284+ u32 tche; /* technology enabled indicator */
285+ u32 alsi; /* current ALS illuminance reading */
286+ u32 bclp; /* backlight brightness to set */
287+ u32 pfit; /* panel fitting state */
288+ u32 cblv; /* current brightness level */
289+ u16 bclm[20]; /* backlight level duty cycle mapping table */
290+ u32 cpfm; /* current panel fitting mode */
291+ u32 epfm; /* enabled panel fitting modes */
292+ u8 plut[74]; /* panel LUT and identifier */
293+ u32 pfmb; /* PWM freq and min brightness */
294+ u8 rsvd[102];
295+} __attribute__((packed));
296+
297+/* ASLE irq request bits */
298+#define ASLE_SET_ALS_ILLUM (1 << 0)
299+#define ASLE_SET_BACKLIGHT (1 << 1)
300+#define ASLE_SET_PFIT (1 << 2)
301+#define ASLE_SET_PWM_FREQ (1 << 3)
302+#define ASLE_REQ_MSK 0xf
303+
304+/* response bits of ASLE irq request */
305+#define ASLE_ALS_ILLUM_FAIL (2<<10)
306+#define ASLE_BACKLIGHT_FAIL (2<<12)
307+#define ASLE_PFIT_FAIL (2<<14)
308+#define ASLE_PWM_FREQ_FAIL (2<<16)
309+
310+/* ASLE backlight brightness to set */
311+#define ASLE_BCLP_VALID (1<<31)
312+#define ASLE_BCLP_MSK (~(1<<31))
313+
314+/* ASLE panel fitting request */
315+#define ASLE_PFIT_VALID (1<<31)
316+#define ASLE_PFIT_CENTER (1<<0)
317+#define ASLE_PFIT_STRETCH_TEXT (1<<1)
318+#define ASLE_PFIT_STRETCH_GFX (1<<2)
319+
320+/* PWM frequency and minimum brightness */
321+#define ASLE_PFMB_BRIGHTNESS_MASK (0xff)
322+#define ASLE_PFMB_BRIGHTNESS_VALID (1<<8)
323+#define ASLE_PFMB_PWM_MASK (0x7ffffe00)
324+#define ASLE_PFMB_PWM_VALID (1<<31)
325+
326+#define ASLE_CBLV_VALID (1<<31)
327+
328+static u32 asle_set_backlight(struct drm_device *dev, u32 bclp)
329+{
330+ struct drm_i915_private *dev_priv = dev->dev_private;
331+ struct opregion_asle *asle = dev_priv->opregion.asle;
332+ u32 blc_pwm_ctl, blc_pwm_ctl2;
333+
334+ if (!(bclp & ASLE_BCLP_VALID))
335+ return ASLE_BACKLIGHT_FAIL;
336+
337+ bclp &= ASLE_BCLP_MSK;
338+ if (bclp < 0 || bclp > 255)
339+ return ASLE_BACKLIGHT_FAIL;
340+
341+ blc_pwm_ctl = I915_READ(BLC_PWM_CTL);
342+ blc_pwm_ctl &= ~BACKLIGHT_DUTY_CYCLE_MASK;
343+ blc_pwm_ctl2 = I915_READ(BLC_PWM_CTL2);
344+
345+ if (blc_pwm_ctl2 & BLM_COMBINATION_MODE)
346+ pci_write_config_dword(dev->pdev, PCI_LBPC, bclp);
347+ else
348+ I915_WRITE(BLC_PWM_CTL, blc_pwm_ctl | ((bclp * 0x101)-1));
349+
350+ asle->cblv = (bclp*0x64)/0xff | ASLE_CBLV_VALID;
351+
352+ return 0;
353+}
354+
355+static u32 asle_set_als_illum(struct drm_device *dev, u32 alsi)
356+{
357+ /* alsi is the current ALS reading in lux. 0 indicates below sensor
358+ range, 0xffff indicates above sensor range. 1-0xfffe are valid */
359+ return 0;
360+}
361+
362+static u32 asle_set_pwm_freq(struct drm_device *dev, u32 pfmb)
363+{
364+ struct drm_i915_private *dev_priv = dev->dev_private;
365+ if (pfmb & ASLE_PFMB_PWM_VALID) {
366+ u32 blc_pwm_ctl = I915_READ(BLC_PWM_CTL);
367+ u32 pwm = pfmb & ASLE_PFMB_PWM_MASK;
368+ blc_pwm_ctl &= BACKLIGHT_DUTY_CYCLE_MASK;
369+ pwm = pwm >> 9;
370+ /* FIXME - what do we do with the PWM? */
371+ }
372+ return 0;
373+}
374+
375+static u32 asle_set_pfit(struct drm_device *dev, u32 pfit)
376+{
377+ /* Panel fitting is currently controlled by the X code, so this is a
378+ noop until modesetting support works fully */
379+ if (!(pfit & ASLE_PFIT_VALID))
380+ return ASLE_PFIT_FAIL;
381+ return 0;
382+}
383+
384+void opregion_asle_intr(struct drm_device *dev)
385+{
386+ struct drm_i915_private *dev_priv = dev->dev_private;
387+ struct opregion_asle *asle = dev_priv->opregion.asle;
388+ u32 asle_stat = 0;
389+ u32 asle_req;
390+
391+ if (!asle)
392+ return;
393+
394+ asle_req = asle->aslc & ASLE_REQ_MSK;
395+
396+ if (!asle_req) {
397+ DRM_DEBUG("non asle set request??\n");
398+ return;
399+ }
400+
401+ if (asle_req & ASLE_SET_ALS_ILLUM)
402+ asle_stat |= asle_set_als_illum(dev, asle->alsi);
403+
404+ if (asle_req & ASLE_SET_BACKLIGHT)
405+ asle_stat |= asle_set_backlight(dev, asle->bclp);
406+
407+ if (asle_req & ASLE_SET_PFIT)
408+ asle_stat |= asle_set_pfit(dev, asle->pfit);
409+
410+ if (asle_req & ASLE_SET_PWM_FREQ)
411+ asle_stat |= asle_set_pwm_freq(dev, asle->pfmb);
412+
413+ asle->aslc = asle_stat;
414+}
415+
416+#define ASLE_ALS_EN (1<<0)
417+#define ASLE_BLC_EN (1<<1)
418+#define ASLE_PFIT_EN (1<<2)
419+#define ASLE_PFMB_EN (1<<3)
420+
421+void opregion_enable_asle(struct drm_device *dev)
422+{
423+ struct drm_i915_private *dev_priv = dev->dev_private;
424+ struct opregion_asle *asle = dev_priv->opregion.asle;
425+
426+ if (asle) {
427+ u32 pipeb_stats = I915_READ(PIPEBSTAT);
428+ if (IS_MOBILE(dev)) {
429+ /* Many devices trigger events with a write to the
430+ legacy backlight controller, so we need to ensure
431+ that it's able to generate interrupts */
432+ I915_WRITE(PIPEBSTAT, pipeb_stats |=
433+ I915_LEGACY_BLC_EVENT_ENABLE);
434+ i915_enable_irq(dev_priv, I915_ASLE_INTERRUPT |
435+ I915_DISPLAY_PIPE_B_EVENT_INTERRUPT);
436+ } else
437+ i915_enable_irq(dev_priv, I915_ASLE_INTERRUPT);
438+
439+ asle->tche = ASLE_ALS_EN | ASLE_BLC_EN | ASLE_PFIT_EN |
440+ ASLE_PFMB_EN;
441+ asle->ardy = 1;
442+ }
443+}
444+
445+#define ACPI_EV_DISPLAY_SWITCH (1<<0)
446+#define ACPI_EV_LID (1<<1)
447+#define ACPI_EV_DOCK (1<<2)
448+
449+static struct intel_opregion *system_opregion;
450+
451+int intel_opregion_video_event(struct notifier_block *nb, unsigned long val,
452+ void *data)
453+{
454+ /* The only video events relevant to opregion are 0x80. These indicate
455+ either a docking event, lid switch or display switch request. In
456+ Linux, these are handled by the dock, button and video drivers.
457+ We might want to fix the video driver to be opregion-aware in
458+ future, but right now we just indicate to the firmware that the
459+ request has been handled */
460+
461+ struct opregion_acpi *acpi;
462+
463+ if (!system_opregion)
464+ return NOTIFY_DONE;
465+
466+ acpi = system_opregion->acpi;
467+ acpi->csts = 0;
468+
469+ return NOTIFY_OK;
470+}
471+
472+static struct notifier_block intel_opregion_notifier = {
473+ .notifier_call = intel_opregion_video_event,
474+};
475+
476+int intel_opregion_init(struct drm_device *dev)
477+{
478+ struct drm_i915_private *dev_priv = dev->dev_private;
479+ struct intel_opregion *opregion = &dev_priv->opregion;
480+ void *base;
481+ u32 asls, mboxes;
482+ int err = 0;
483+
484+ pci_read_config_dword(dev->pdev, PCI_ASLS, &asls);
485+ DRM_DEBUG("graphic opregion physical addr: 0x%x\n", asls);
486+ if (asls == 0) {
487+ DRM_DEBUG("ACPI OpRegion not supported!\n");
488+ return -ENOTSUPP;
489+ }
490+
491+ base = ioremap(asls, OPREGION_SZ);
492+ if (!base)
493+ return -ENOMEM;
494+
495+ opregion->header = base;
496+ if (memcmp(opregion->header->signature, OPREGION_SIGNATURE, 16)) {
497+ DRM_DEBUG("opregion signature mismatch\n");
498+ err = -EINVAL;
499+ goto err_out;
500+ }
501+
502+ mboxes = opregion->header->mboxes;
503+ if (mboxes & MBOX_ACPI) {
504+ DRM_DEBUG("Public ACPI methods supported\n");
505+ opregion->acpi = base + OPREGION_ACPI_OFFSET;
506+ } else {
507+ DRM_DEBUG("Public ACPI methods not supported\n");
508+ err = -ENOTSUPP;
509+ goto err_out;
510+ }
511+ opregion->enabled = 1;
512+
513+ if (mboxes & MBOX_SWSCI) {
514+ DRM_DEBUG("SWSCI supported\n");
515+ opregion->swsci = base + OPREGION_SWSCI_OFFSET;
516+ }
517+ if (mboxes & MBOX_ASLE) {
518+ DRM_DEBUG("ASLE supported\n");
519+ opregion->asle = base + OPREGION_ASLE_OFFSET;
520+ }
521+
522+ /* Notify BIOS we are ready to handle ACPI video ext notifs.
523+ * Right now, all the events are handled by the ACPI video module.
524+ * We don't actually need to do anything with them. */
525+ opregion->acpi->csts = 0;
526+ opregion->acpi->drdy = 1;
527+
528+ system_opregion = opregion;
529+ register_acpi_notifier(&intel_opregion_notifier);
530+
531+ return 0;
532+
533+err_out:
534+ iounmap(opregion->header);
535+ opregion->header = NULL;
536+ return err;
537+}
538+
539+void intel_opregion_free(struct drm_device *dev)
540+{
541+ struct drm_i915_private *dev_priv = dev->dev_private;
542+ struct intel_opregion *opregion = &dev_priv->opregion;
543+
544+ if (!opregion->enabled)
545+ return;
546+
547+ opregion->acpi->drdy = 0;
548+
549+ system_opregion = NULL;
550+ unregister_acpi_notifier(&intel_opregion_notifier);
551+
552+ /* just clear all opregion memory pointers now */
553+ iounmap(opregion->header);
554+ opregion->header = NULL;
555+ opregion->acpi = NULL;
556+ opregion->swsci = NULL;
557+ opregion->asle = NULL;
558+
559+ opregion->enabled = 0;
560+}
561diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
562index 477c64e..43ad2cb 100644
563--- a/drivers/gpu/drm/i915/i915_reg.h
564+++ b/drivers/gpu/drm/i915/i915_reg.h
565@@ -740,6 +740,7 @@
566 #define BLC_PWM_CTL 0x61254
567 #define BACKLIGHT_MODULATION_FREQ_SHIFT (17)
568 #define BLC_PWM_CTL2 0x61250 /* 965+ only */
569+#define BLM_COMBINATION_MODE (1 << 30)
570 /*
571 * This is the most significant 15 bits of the number of backlight cycles in a
572 * complete cycle of the modulated backlight control.
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0009-drm-fix-sysfs-error-path.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0009-drm-fix-sysfs-error-path.patch
new file mode 100644
index 0000000000..8dea824804
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0009-drm-fix-sysfs-error-path.patch
@@ -0,0 +1,23 @@
1commit 2e9c9eedfe0be777c051a2198dddf459adcc407b
2Author: Dave Airlie <airlied@redhat.com>
3Date: Tue Sep 2 10:06:06 2008 +1000
4
5 drm: fix sysfs error path.
6
7 Pointed out by Roel Kluin on dri-devel.
8
9 Signed-off-by: Dave Airlie <airlied@redhat.com>
10
11diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
12index af211a0..1611b9b 100644
13--- a/drivers/gpu/drm/drm_sysfs.c
14+++ b/drivers/gpu/drm/drm_sysfs.c
15@@ -184,7 +184,7 @@ int drm_sysfs_device_add(struct drm_minor *minor)
16 err_out_files:
17 if (i > 0)
18 for (j = 0; j < i; j++)
19- device_remove_file(&minor->kdev, &device_attrs[i]);
20+ device_remove_file(&minor->kdev, &device_attrs[j]);
21 device_unregister(&minor->kdev);
22 err_out:
23
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0010-i915-separate-suspend-resume-functions.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0010-i915-separate-suspend-resume-functions.patch
new file mode 100644
index 0000000000..897d50c39b
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0010-i915-separate-suspend-resume-functions.patch
@@ -0,0 +1,1079 @@
1commit a850828c640735fb410c782717c9eb7f8474e356
2Author: Jesse Barnes <jbarnes@virtuousgeek.org>
3Date: Mon Aug 25 15:11:06 2008 -0700
4
5 separate i915 suspend/resume functions into their own file
6
7 [Patch against drm-next. Consider this a trial balloon for our new Linux
8 development model.]
9
10 This is a big chunk of code. Separating it out makes it easier to change
11 without churn on the main i915_drv.c file (and there will be churn as we
12 fix bugs and add things like kernel mode setting). Also makes it easier
13 to share this file with BSD.
14
15 Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
16 Signed-off-by: Dave Airlie <airlied@redhat.com>
17
18diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
19index b032808..c4bbda6 100644
20--- a/drivers/gpu/drm/i915/Makefile
21+++ b/drivers/gpu/drm/i915/Makefile
22@@ -3,7 +3,8 @@
23 # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
24
25 ccflags-y := -Iinclude/drm
26-i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o i915_opregion.o
27+i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o i915_opregion.o \
28+ i915_suspend.o
29
30 i915-$(CONFIG_COMPAT) += i915_ioc32.o
31
32diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
33index d95eca2..eff66ed 100644
34--- a/drivers/gpu/drm/i915/i915_drv.c
35+++ b/drivers/gpu/drm/i915/i915_drv.c
36@@ -38,211 +38,9 @@ static struct pci_device_id pciidlist[] = {
37 i915_PCI_IDS
38 };
39
40-enum pipe {
41- PIPE_A = 0,
42- PIPE_B,
43-};
44-
45-static bool i915_pipe_enabled(struct drm_device *dev, enum pipe pipe)
46-{
47- struct drm_i915_private *dev_priv = dev->dev_private;
48-
49- if (pipe == PIPE_A)
50- return (I915_READ(DPLL_A) & DPLL_VCO_ENABLE);
51- else
52- return (I915_READ(DPLL_B) & DPLL_VCO_ENABLE);
53-}
54-
55-static void i915_save_palette(struct drm_device *dev, enum pipe pipe)
56-{
57- struct drm_i915_private *dev_priv = dev->dev_private;
58- unsigned long reg = (pipe == PIPE_A ? PALETTE_A : PALETTE_B);
59- u32 *array;
60- int i;
61-
62- if (!i915_pipe_enabled(dev, pipe))
63- return;
64-
65- if (pipe == PIPE_A)
66- array = dev_priv->save_palette_a;
67- else
68- array = dev_priv->save_palette_b;
69-
70- for(i = 0; i < 256; i++)
71- array[i] = I915_READ(reg + (i << 2));
72-}
73-
74-static void i915_restore_palette(struct drm_device *dev, enum pipe pipe)
75-{
76- struct drm_i915_private *dev_priv = dev->dev_private;
77- unsigned long reg = (pipe == PIPE_A ? PALETTE_A : PALETTE_B);
78- u32 *array;
79- int i;
80-
81- if (!i915_pipe_enabled(dev, pipe))
82- return;
83-
84- if (pipe == PIPE_A)
85- array = dev_priv->save_palette_a;
86- else
87- array = dev_priv->save_palette_b;
88-
89- for(i = 0; i < 256; i++)
90- I915_WRITE(reg + (i << 2), array[i]);
91-}
92-
93-static u8 i915_read_indexed(u16 index_port, u16 data_port, u8 reg)
94-{
95- outb(reg, index_port);
96- return inb(data_port);
97-}
98-
99-static u8 i915_read_ar(u16 st01, u8 reg, u16 palette_enable)
100-{
101- inb(st01);
102- outb(palette_enable | reg, VGA_AR_INDEX);
103- return inb(VGA_AR_DATA_READ);
104-}
105-
106-static void i915_write_ar(u8 st01, u8 reg, u8 val, u16 palette_enable)
107-{
108- inb(st01);
109- outb(palette_enable | reg, VGA_AR_INDEX);
110- outb(val, VGA_AR_DATA_WRITE);
111-}
112-
113-static void i915_write_indexed(u16 index_port, u16 data_port, u8 reg, u8 val)
114-{
115- outb(reg, index_port);
116- outb(val, data_port);
117-}
118-
119-static void i915_save_vga(struct drm_device *dev)
120-{
121- struct drm_i915_private *dev_priv = dev->dev_private;
122- int i;
123- u16 cr_index, cr_data, st01;
124-
125- /* VGA color palette registers */
126- dev_priv->saveDACMASK = inb(VGA_DACMASK);
127- /* DACCRX automatically increments during read */
128- outb(0, VGA_DACRX);
129- /* Read 3 bytes of color data from each index */
130- for (i = 0; i < 256 * 3; i++)
131- dev_priv->saveDACDATA[i] = inb(VGA_DACDATA);
132-
133- /* MSR bits */
134- dev_priv->saveMSR = inb(VGA_MSR_READ);
135- if (dev_priv->saveMSR & VGA_MSR_CGA_MODE) {
136- cr_index = VGA_CR_INDEX_CGA;
137- cr_data = VGA_CR_DATA_CGA;
138- st01 = VGA_ST01_CGA;
139- } else {
140- cr_index = VGA_CR_INDEX_MDA;
141- cr_data = VGA_CR_DATA_MDA;
142- st01 = VGA_ST01_MDA;
143- }
144-
145- /* CRT controller regs */
146- i915_write_indexed(cr_index, cr_data, 0x11,
147- i915_read_indexed(cr_index, cr_data, 0x11) &
148- (~0x80));
149- for (i = 0; i <= 0x24; i++)
150- dev_priv->saveCR[i] =
151- i915_read_indexed(cr_index, cr_data, i);
152- /* Make sure we don't turn off CR group 0 writes */
153- dev_priv->saveCR[0x11] &= ~0x80;
154-
155- /* Attribute controller registers */
156- inb(st01);
157- dev_priv->saveAR_INDEX = inb(VGA_AR_INDEX);
158- for (i = 0; i <= 0x14; i++)
159- dev_priv->saveAR[i] = i915_read_ar(st01, i, 0);
160- inb(st01);
161- outb(dev_priv->saveAR_INDEX, VGA_AR_INDEX);
162- inb(st01);
163-
164- /* Graphics controller registers */
165- for (i = 0; i < 9; i++)
166- dev_priv->saveGR[i] =
167- i915_read_indexed(VGA_GR_INDEX, VGA_GR_DATA, i);
168-
169- dev_priv->saveGR[0x10] =
170- i915_read_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x10);
171- dev_priv->saveGR[0x11] =
172- i915_read_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x11);
173- dev_priv->saveGR[0x18] =
174- i915_read_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x18);
175-
176- /* Sequencer registers */
177- for (i = 0; i < 8; i++)
178- dev_priv->saveSR[i] =
179- i915_read_indexed(VGA_SR_INDEX, VGA_SR_DATA, i);
180-}
181-
182-static void i915_restore_vga(struct drm_device *dev)
183-{
184- struct drm_i915_private *dev_priv = dev->dev_private;
185- int i;
186- u16 cr_index, cr_data, st01;
187-
188- /* MSR bits */
189- outb(dev_priv->saveMSR, VGA_MSR_WRITE);
190- if (dev_priv->saveMSR & VGA_MSR_CGA_MODE) {
191- cr_index = VGA_CR_INDEX_CGA;
192- cr_data = VGA_CR_DATA_CGA;
193- st01 = VGA_ST01_CGA;
194- } else {
195- cr_index = VGA_CR_INDEX_MDA;
196- cr_data = VGA_CR_DATA_MDA;
197- st01 = VGA_ST01_MDA;
198- }
199-
200- /* Sequencer registers, don't write SR07 */
201- for (i = 0; i < 7; i++)
202- i915_write_indexed(VGA_SR_INDEX, VGA_SR_DATA, i,
203- dev_priv->saveSR[i]);
204-
205- /* CRT controller regs */
206- /* Enable CR group 0 writes */
207- i915_write_indexed(cr_index, cr_data, 0x11, dev_priv->saveCR[0x11]);
208- for (i = 0; i <= 0x24; i++)
209- i915_write_indexed(cr_index, cr_data, i, dev_priv->saveCR[i]);
210-
211- /* Graphics controller regs */
212- for (i = 0; i < 9; i++)
213- i915_write_indexed(VGA_GR_INDEX, VGA_GR_DATA, i,
214- dev_priv->saveGR[i]);
215-
216- i915_write_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x10,
217- dev_priv->saveGR[0x10]);
218- i915_write_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x11,
219- dev_priv->saveGR[0x11]);
220- i915_write_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x18,
221- dev_priv->saveGR[0x18]);
222-
223- /* Attribute controller registers */
224- inb(st01);
225- for (i = 0; i <= 0x14; i++)
226- i915_write_ar(st01, i, dev_priv->saveAR[i], 0);
227- inb(st01); /* switch back to index mode */
228- outb(dev_priv->saveAR_INDEX | 0x20, VGA_AR_INDEX);
229- inb(st01);
230-
231- /* VGA color palette registers */
232- outb(dev_priv->saveDACMASK, VGA_DACMASK);
233- /* DACCRX automatically increments during read */
234- outb(0, VGA_DACWX);
235- /* Read 3 bytes of color data from each index */
236- for (i = 0; i < 256 * 3; i++)
237- outb(dev_priv->saveDACDATA[i], VGA_DACDATA);
238-
239-}
240-
241 static int i915_suspend(struct drm_device *dev, pm_message_t state)
242 {
243 struct drm_i915_private *dev_priv = dev->dev_private;
244- int i;
245
246 if (!dev || !dev_priv) {
247 printk(KERN_ERR "dev: %p, dev_priv: %p\n", dev, dev_priv);
248@@ -254,122 +52,8 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state)
249 return 0;
250
251 pci_save_state(dev->pdev);
252- pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB);
253-
254- /* Display arbitration control */
255- dev_priv->saveDSPARB = I915_READ(DSPARB);
256-
257- /* Pipe & plane A info */
258- dev_priv->savePIPEACONF = I915_READ(PIPEACONF);
259- dev_priv->savePIPEASRC = I915_READ(PIPEASRC);
260- dev_priv->saveFPA0 = I915_READ(FPA0);
261- dev_priv->saveFPA1 = I915_READ(FPA1);
262- dev_priv->saveDPLL_A = I915_READ(DPLL_A);
263- if (IS_I965G(dev))
264- dev_priv->saveDPLL_A_MD = I915_READ(DPLL_A_MD);
265- dev_priv->saveHTOTAL_A = I915_READ(HTOTAL_A);
266- dev_priv->saveHBLANK_A = I915_READ(HBLANK_A);
267- dev_priv->saveHSYNC_A = I915_READ(HSYNC_A);
268- dev_priv->saveVTOTAL_A = I915_READ(VTOTAL_A);
269- dev_priv->saveVBLANK_A = I915_READ(VBLANK_A);
270- dev_priv->saveVSYNC_A = I915_READ(VSYNC_A);
271- dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A);
272-
273- dev_priv->saveDSPACNTR = I915_READ(DSPACNTR);
274- dev_priv->saveDSPASTRIDE = I915_READ(DSPASTRIDE);
275- dev_priv->saveDSPASIZE = I915_READ(DSPASIZE);
276- dev_priv->saveDSPAPOS = I915_READ(DSPAPOS);
277- dev_priv->saveDSPAADDR = I915_READ(DSPAADDR);
278- if (IS_I965G(dev)) {
279- dev_priv->saveDSPASURF = I915_READ(DSPASURF);
280- dev_priv->saveDSPATILEOFF = I915_READ(DSPATILEOFF);
281- }
282- i915_save_palette(dev, PIPE_A);
283- dev_priv->savePIPEASTAT = I915_READ(PIPEASTAT);
284-
285- /* Pipe & plane B info */
286- dev_priv->savePIPEBCONF = I915_READ(PIPEBCONF);
287- dev_priv->savePIPEBSRC = I915_READ(PIPEBSRC);
288- dev_priv->saveFPB0 = I915_READ(FPB0);
289- dev_priv->saveFPB1 = I915_READ(FPB1);
290- dev_priv->saveDPLL_B = I915_READ(DPLL_B);
291- if (IS_I965G(dev))
292- dev_priv->saveDPLL_B_MD = I915_READ(DPLL_B_MD);
293- dev_priv->saveHTOTAL_B = I915_READ(HTOTAL_B);
294- dev_priv->saveHBLANK_B = I915_READ(HBLANK_B);
295- dev_priv->saveHSYNC_B = I915_READ(HSYNC_B);
296- dev_priv->saveVTOTAL_B = I915_READ(VTOTAL_B);
297- dev_priv->saveVBLANK_B = I915_READ(VBLANK_B);
298- dev_priv->saveVSYNC_B = I915_READ(VSYNC_B);
299- dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A);
300-
301- dev_priv->saveDSPBCNTR = I915_READ(DSPBCNTR);
302- dev_priv->saveDSPBSTRIDE = I915_READ(DSPBSTRIDE);
303- dev_priv->saveDSPBSIZE = I915_READ(DSPBSIZE);
304- dev_priv->saveDSPBPOS = I915_READ(DSPBPOS);
305- dev_priv->saveDSPBADDR = I915_READ(DSPBADDR);
306- if (IS_I965GM(dev) || IS_IGD_GM(dev)) {
307- dev_priv->saveDSPBSURF = I915_READ(DSPBSURF);
308- dev_priv->saveDSPBTILEOFF = I915_READ(DSPBTILEOFF);
309- }
310- i915_save_palette(dev, PIPE_B);
311- dev_priv->savePIPEBSTAT = I915_READ(PIPEBSTAT);
312-
313- /* CRT state */
314- dev_priv->saveADPA = I915_READ(ADPA);
315
316- /* LVDS state */
317- dev_priv->savePP_CONTROL = I915_READ(PP_CONTROL);
318- dev_priv->savePFIT_PGM_RATIOS = I915_READ(PFIT_PGM_RATIOS);
319- dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_CTL);
320- if (IS_I965G(dev))
321- dev_priv->saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_CTL2);
322- if (IS_MOBILE(dev) && !IS_I830(dev))
323- dev_priv->saveLVDS = I915_READ(LVDS);
324- if (!IS_I830(dev) && !IS_845G(dev))
325- dev_priv->savePFIT_CONTROL = I915_READ(PFIT_CONTROL);
326- dev_priv->savePP_ON_DELAYS = I915_READ(PP_ON_DELAYS);
327- dev_priv->savePP_OFF_DELAYS = I915_READ(PP_OFF_DELAYS);
328- dev_priv->savePP_DIVISOR = I915_READ(PP_DIVISOR);
329-
330- /* FIXME: save TV & SDVO state */
331-
332- /* FBC state */
333- dev_priv->saveFBC_CFB_BASE = I915_READ(FBC_CFB_BASE);
334- dev_priv->saveFBC_LL_BASE = I915_READ(FBC_LL_BASE);
335- dev_priv->saveFBC_CONTROL2 = I915_READ(FBC_CONTROL2);
336- dev_priv->saveFBC_CONTROL = I915_READ(FBC_CONTROL);
337-
338- /* Interrupt state */
339- dev_priv->saveIIR = I915_READ(IIR);
340- dev_priv->saveIER = I915_READ(IER);
341- dev_priv->saveIMR = I915_READ(IMR);
342-
343- /* VGA state */
344- dev_priv->saveVGA0 = I915_READ(VGA0);
345- dev_priv->saveVGA1 = I915_READ(VGA1);
346- dev_priv->saveVGA_PD = I915_READ(VGA_PD);
347- dev_priv->saveVGACNTRL = I915_READ(VGACNTRL);
348-
349- /* Clock gating state */
350- dev_priv->saveD_STATE = I915_READ(D_STATE);
351- dev_priv->saveCG_2D_DIS = I915_READ(CG_2D_DIS);
352-
353- /* Cache mode state */
354- dev_priv->saveCACHE_MODE_0 = I915_READ(CACHE_MODE_0);
355-
356- /* Memory Arbitration state */
357- dev_priv->saveMI_ARB_STATE = I915_READ(MI_ARB_STATE);
358-
359- /* Scratch space */
360- for (i = 0; i < 16; i++) {
361- dev_priv->saveSWF0[i] = I915_READ(SWF00 + (i << 2));
362- dev_priv->saveSWF1[i] = I915_READ(SWF10 + (i << 2));
363- }
364- for (i = 0; i < 3; i++)
365- dev_priv->saveSWF2[i] = I915_READ(SWF30 + (i << 2));
366-
367- i915_save_vga(dev);
368+ i915_save_state(dev);
369
370 intel_opregion_free(dev);
371
372@@ -384,155 +68,13 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state)
373
374 static int i915_resume(struct drm_device *dev)
375 {
376- struct drm_i915_private *dev_priv = dev->dev_private;
377- int i;
378-
379 pci_set_power_state(dev->pdev, PCI_D0);
380 pci_restore_state(dev->pdev);
381 if (pci_enable_device(dev->pdev))
382 return -1;
383 pci_set_master(dev->pdev);
384
385- pci_write_config_byte(dev->pdev, LBB, dev_priv->saveLBB);
386-
387- I915_WRITE(DSPARB, dev_priv->saveDSPARB);
388-
389- /* Pipe & plane A info */
390- /* Prime the clock */
391- if (dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) {
392- I915_WRITE(DPLL_A, dev_priv->saveDPLL_A &
393- ~DPLL_VCO_ENABLE);
394- udelay(150);
395- }
396- I915_WRITE(FPA0, dev_priv->saveFPA0);
397- I915_WRITE(FPA1, dev_priv->saveFPA1);
398- /* Actually enable it */
399- I915_WRITE(DPLL_A, dev_priv->saveDPLL_A);
400- udelay(150);
401- if (IS_I965G(dev))
402- I915_WRITE(DPLL_A_MD, dev_priv->saveDPLL_A_MD);
403- udelay(150);
404-
405- /* Restore mode */
406- I915_WRITE(HTOTAL_A, dev_priv->saveHTOTAL_A);
407- I915_WRITE(HBLANK_A, dev_priv->saveHBLANK_A);
408- I915_WRITE(HSYNC_A, dev_priv->saveHSYNC_A);
409- I915_WRITE(VTOTAL_A, dev_priv->saveVTOTAL_A);
410- I915_WRITE(VBLANK_A, dev_priv->saveVBLANK_A);
411- I915_WRITE(VSYNC_A, dev_priv->saveVSYNC_A);
412- I915_WRITE(BCLRPAT_A, dev_priv->saveBCLRPAT_A);
413-
414- /* Restore plane info */
415- I915_WRITE(DSPASIZE, dev_priv->saveDSPASIZE);
416- I915_WRITE(DSPAPOS, dev_priv->saveDSPAPOS);
417- I915_WRITE(PIPEASRC, dev_priv->savePIPEASRC);
418- I915_WRITE(DSPAADDR, dev_priv->saveDSPAADDR);
419- I915_WRITE(DSPASTRIDE, dev_priv->saveDSPASTRIDE);
420- if (IS_I965G(dev)) {
421- I915_WRITE(DSPASURF, dev_priv->saveDSPASURF);
422- I915_WRITE(DSPATILEOFF, dev_priv->saveDSPATILEOFF);
423- }
424-
425- I915_WRITE(PIPEACONF, dev_priv->savePIPEACONF);
426-
427- i915_restore_palette(dev, PIPE_A);
428- /* Enable the plane */
429- I915_WRITE(DSPACNTR, dev_priv->saveDSPACNTR);
430- I915_WRITE(DSPAADDR, I915_READ(DSPAADDR));
431-
432- /* Pipe & plane B info */
433- if (dev_priv->saveDPLL_B & DPLL_VCO_ENABLE) {
434- I915_WRITE(DPLL_B, dev_priv->saveDPLL_B &
435- ~DPLL_VCO_ENABLE);
436- udelay(150);
437- }
438- I915_WRITE(FPB0, dev_priv->saveFPB0);
439- I915_WRITE(FPB1, dev_priv->saveFPB1);
440- /* Actually enable it */
441- I915_WRITE(DPLL_B, dev_priv->saveDPLL_B);
442- udelay(150);
443- if (IS_I965G(dev))
444- I915_WRITE(DPLL_B_MD, dev_priv->saveDPLL_B_MD);
445- udelay(150);
446-
447- /* Restore mode */
448- I915_WRITE(HTOTAL_B, dev_priv->saveHTOTAL_B);
449- I915_WRITE(HBLANK_B, dev_priv->saveHBLANK_B);
450- I915_WRITE(HSYNC_B, dev_priv->saveHSYNC_B);
451- I915_WRITE(VTOTAL_B, dev_priv->saveVTOTAL_B);
452- I915_WRITE(VBLANK_B, dev_priv->saveVBLANK_B);
453- I915_WRITE(VSYNC_B, dev_priv->saveVSYNC_B);
454- I915_WRITE(BCLRPAT_B, dev_priv->saveBCLRPAT_B);
455-
456- /* Restore plane info */
457- I915_WRITE(DSPBSIZE, dev_priv->saveDSPBSIZE);
458- I915_WRITE(DSPBPOS, dev_priv->saveDSPBPOS);
459- I915_WRITE(PIPEBSRC, dev_priv->savePIPEBSRC);
460- I915_WRITE(DSPBADDR, dev_priv->saveDSPBADDR);
461- I915_WRITE(DSPBSTRIDE, dev_priv->saveDSPBSTRIDE);
462- if (IS_I965G(dev)) {
463- I915_WRITE(DSPBSURF, dev_priv->saveDSPBSURF);
464- I915_WRITE(DSPBTILEOFF, dev_priv->saveDSPBTILEOFF);
465- }
466-
467- I915_WRITE(PIPEBCONF, dev_priv->savePIPEBCONF);
468-
469- i915_restore_palette(dev, PIPE_B);
470- /* Enable the plane */
471- I915_WRITE(DSPBCNTR, dev_priv->saveDSPBCNTR);
472- I915_WRITE(DSPBADDR, I915_READ(DSPBADDR));
473-
474- /* CRT state */
475- I915_WRITE(ADPA, dev_priv->saveADPA);
476-
477- /* LVDS state */
478- if (IS_I965G(dev))
479- I915_WRITE(BLC_PWM_CTL2, dev_priv->saveBLC_PWM_CTL2);
480- if (IS_MOBILE(dev) && !IS_I830(dev))
481- I915_WRITE(LVDS, dev_priv->saveLVDS);
482- if (!IS_I830(dev) && !IS_845G(dev))
483- I915_WRITE(PFIT_CONTROL, dev_priv->savePFIT_CONTROL);
484-
485- I915_WRITE(PFIT_PGM_RATIOS, dev_priv->savePFIT_PGM_RATIOS);
486- I915_WRITE(BLC_PWM_CTL, dev_priv->saveBLC_PWM_CTL);
487- I915_WRITE(PP_ON_DELAYS, dev_priv->savePP_ON_DELAYS);
488- I915_WRITE(PP_OFF_DELAYS, dev_priv->savePP_OFF_DELAYS);
489- I915_WRITE(PP_DIVISOR, dev_priv->savePP_DIVISOR);
490- I915_WRITE(PP_CONTROL, dev_priv->savePP_CONTROL);
491-
492- /* FIXME: restore TV & SDVO state */
493-
494- /* FBC info */
495- I915_WRITE(FBC_CFB_BASE, dev_priv->saveFBC_CFB_BASE);
496- I915_WRITE(FBC_LL_BASE, dev_priv->saveFBC_LL_BASE);
497- I915_WRITE(FBC_CONTROL2, dev_priv->saveFBC_CONTROL2);
498- I915_WRITE(FBC_CONTROL, dev_priv->saveFBC_CONTROL);
499-
500- /* VGA state */
501- I915_WRITE(VGACNTRL, dev_priv->saveVGACNTRL);
502- I915_WRITE(VGA0, dev_priv->saveVGA0);
503- I915_WRITE(VGA1, dev_priv->saveVGA1);
504- I915_WRITE(VGA_PD, dev_priv->saveVGA_PD);
505- udelay(150);
506-
507- /* Clock gating state */
508- I915_WRITE (D_STATE, dev_priv->saveD_STATE);
509- I915_WRITE(CG_2D_DIS, dev_priv->saveCG_2D_DIS);
510-
511- /* Cache mode state */
512- I915_WRITE (CACHE_MODE_0, dev_priv->saveCACHE_MODE_0 | 0xffff0000);
513-
514- /* Memory arbitration state */
515- I915_WRITE (MI_ARB_STATE, dev_priv->saveMI_ARB_STATE | 0xffff0000);
516-
517- for (i = 0; i < 16; i++) {
518- I915_WRITE(SWF00 + (i << 2), dev_priv->saveSWF0[i]);
519- I915_WRITE(SWF10 + (i << 2), dev_priv->saveSWF1[i+7]);
520- }
521- for (i = 0; i < 3; i++)
522- I915_WRITE(SWF30 + (i << 2), dev_priv->saveSWF2[i]);
523-
524- i915_restore_vga(dev);
525+ i915_restore_state(dev);
526
527 intel_opregion_init(dev);
528
529diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
530index e4bd01c..a82b487 100644
531--- a/drivers/gpu/drm/i915/i915_drv.h
532+++ b/drivers/gpu/drm/i915/i915_drv.h
533@@ -41,6 +41,11 @@
534 #define DRIVER_DESC "Intel Graphics"
535 #define DRIVER_DATE "20060119"
536
537+enum pipe {
538+ PIPE_A = 0,
539+ PIPE_B,
540+};
541+
542 /* Interface history:
543 *
544 * 1.1: Original.
545@@ -269,6 +274,10 @@ extern void i915_mem_takedown(struct mem_block **heap);
546 extern void i915_mem_release(struct drm_device * dev,
547 struct drm_file *file_priv, struct mem_block *heap);
548
549+/* i915_suspend.c */
550+extern int i915_save_state(struct drm_device *dev);
551+extern int i915_restore_state(struct drm_device *dev);
552+
553 /* i915_opregion.c */
554 extern int intel_opregion_init(struct drm_device *dev);
555 extern void intel_opregion_free(struct drm_device *dev);
556@@ -279,6 +288,8 @@ extern void opregion_enable_asle(struct drm_device *dev);
557 #define I915_WRITE(reg,val) DRM_WRITE32(dev_priv->mmio_map, (reg), (val))
558 #define I915_READ16(reg) DRM_READ16(dev_priv->mmio_map, (reg))
559 #define I915_WRITE16(reg,val) DRM_WRITE16(dev_priv->mmio_map, (reg), (val))
560+#define I915_READ8(reg) DRM_READ8(dev_priv->mmio_map, (reg))
561+#define I915_WRITE8(reg,val) DRM_WRITE8(dev_priv->mmio_map, (reg), (val))
562
563 #define I915_VERBOSE 0
564
565diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c
566new file mode 100644
567index 0000000..e0c1fe4
568--- /dev/null
569+++ b/drivers/gpu/drm/i915/i915_suspend.c
570@@ -0,0 +1,509 @@
571+/*
572+ *
573+ * Copyright 2008 (c) Intel Corporation
574+ * Jesse Barnes <jbarnes@virtuousgeek.org>
575+ *
576+ * Permission is hereby granted, free of charge, to any person obtaining a
577+ * copy of this software and associated documentation files (the
578+ * "Software"), to deal in the Software without restriction, including
579+ * without limitation the rights to use, copy, modify, merge, publish,
580+ * distribute, sub license, and/or sell copies of the Software, and to
581+ * permit persons to whom the Software is furnished to do so, subject to
582+ * the following conditions:
583+ *
584+ * The above copyright notice and this permission notice (including the
585+ * next paragraph) shall be included in all copies or substantial portions
586+ * of the Software.
587+ *
588+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
589+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
590+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
591+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
592+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
593+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
594+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
595+ */
596+
597+#include "drmP.h"
598+#include "drm.h"
599+#include "i915_drm.h"
600+#include "i915_drv.h"
601+
602+static bool i915_pipe_enabled(struct drm_device *dev, enum pipe pipe)
603+{
604+ struct drm_i915_private *dev_priv = dev->dev_private;
605+
606+ if (pipe == PIPE_A)
607+ return (I915_READ(DPLL_A) & DPLL_VCO_ENABLE);
608+ else
609+ return (I915_READ(DPLL_B) & DPLL_VCO_ENABLE);
610+}
611+
612+static void i915_save_palette(struct drm_device *dev, enum pipe pipe)
613+{
614+ struct drm_i915_private *dev_priv = dev->dev_private;
615+ unsigned long reg = (pipe == PIPE_A ? PALETTE_A : PALETTE_B);
616+ u32 *array;
617+ int i;
618+
619+ if (!i915_pipe_enabled(dev, pipe))
620+ return;
621+
622+ if (pipe == PIPE_A)
623+ array = dev_priv->save_palette_a;
624+ else
625+ array = dev_priv->save_palette_b;
626+
627+ for(i = 0; i < 256; i++)
628+ array[i] = I915_READ(reg + (i << 2));
629+}
630+
631+static void i915_restore_palette(struct drm_device *dev, enum pipe pipe)
632+{
633+ struct drm_i915_private *dev_priv = dev->dev_private;
634+ unsigned long reg = (pipe == PIPE_A ? PALETTE_A : PALETTE_B);
635+ u32 *array;
636+ int i;
637+
638+ if (!i915_pipe_enabled(dev, pipe))
639+ return;
640+
641+ if (pipe == PIPE_A)
642+ array = dev_priv->save_palette_a;
643+ else
644+ array = dev_priv->save_palette_b;
645+
646+ for(i = 0; i < 256; i++)
647+ I915_WRITE(reg + (i << 2), array[i]);
648+}
649+
650+static u8 i915_read_indexed(struct drm_device *dev, u16 index_port, u16 data_port, u8 reg)
651+{
652+ struct drm_i915_private *dev_priv = dev->dev_private;
653+
654+ I915_WRITE8(index_port, reg);
655+ return I915_READ8(data_port);
656+}
657+
658+static u8 i915_read_ar(struct drm_device *dev, u16 st01, u8 reg, u16 palette_enable)
659+{
660+ struct drm_i915_private *dev_priv = dev->dev_private;
661+
662+ I915_READ8(st01);
663+ I915_WRITE8(VGA_AR_INDEX, palette_enable | reg);
664+ return I915_READ8(VGA_AR_DATA_READ);
665+}
666+
667+static void i915_write_ar(struct drm_device *dev, u16 st01, u8 reg, u8 val, u16 palette_enable)
668+{
669+ struct drm_i915_private *dev_priv = dev->dev_private;
670+
671+ I915_READ8(st01);
672+ I915_WRITE8(VGA_AR_INDEX, palette_enable | reg);
673+ I915_WRITE8(VGA_AR_DATA_WRITE, val);
674+}
675+
676+static void i915_write_indexed(struct drm_device *dev, u16 index_port, u16 data_port, u8 reg, u8 val)
677+{
678+ struct drm_i915_private *dev_priv = dev->dev_private;
679+
680+ I915_WRITE8(index_port, reg);
681+ I915_WRITE8(data_port, val);
682+}
683+
684+static void i915_save_vga(struct drm_device *dev)
685+{
686+ struct drm_i915_private *dev_priv = dev->dev_private;
687+ int i;
688+ u16 cr_index, cr_data, st01;
689+
690+ /* VGA color palette registers */
691+ dev_priv->saveDACMASK = I915_READ8(VGA_DACMASK);
692+ /* DACCRX automatically increments during read */
693+ I915_WRITE8(VGA_DACRX, 0);
694+ /* Read 3 bytes of color data from each index */
695+ for (i = 0; i < 256 * 3; i++)
696+ dev_priv->saveDACDATA[i] = I915_READ8(VGA_DACDATA);
697+
698+ /* MSR bits */
699+ dev_priv->saveMSR = I915_READ8(VGA_MSR_READ);
700+ if (dev_priv->saveMSR & VGA_MSR_CGA_MODE) {
701+ cr_index = VGA_CR_INDEX_CGA;
702+ cr_data = VGA_CR_DATA_CGA;
703+ st01 = VGA_ST01_CGA;
704+ } else {
705+ cr_index = VGA_CR_INDEX_MDA;
706+ cr_data = VGA_CR_DATA_MDA;
707+ st01 = VGA_ST01_MDA;
708+ }
709+
710+ /* CRT controller regs */
711+ i915_write_indexed(dev, cr_index, cr_data, 0x11,
712+ i915_read_indexed(dev, cr_index, cr_data, 0x11) &
713+ (~0x80));
714+ for (i = 0; i <= 0x24; i++)
715+ dev_priv->saveCR[i] =
716+ i915_read_indexed(dev, cr_index, cr_data, i);
717+ /* Make sure we don't turn off CR group 0 writes */
718+ dev_priv->saveCR[0x11] &= ~0x80;
719+
720+ /* Attribute controller registers */
721+ I915_READ8(st01);
722+ dev_priv->saveAR_INDEX = I915_READ8(VGA_AR_INDEX);
723+ for (i = 0; i <= 0x14; i++)
724+ dev_priv->saveAR[i] = i915_read_ar(dev, st01, i, 0);
725+ I915_READ8(st01);
726+ I915_WRITE8(VGA_AR_INDEX, dev_priv->saveAR_INDEX);
727+ I915_READ8(st01);
728+
729+ /* Graphics controller registers */
730+ for (i = 0; i < 9; i++)
731+ dev_priv->saveGR[i] =
732+ i915_read_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, i);
733+
734+ dev_priv->saveGR[0x10] =
735+ i915_read_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x10);
736+ dev_priv->saveGR[0x11] =
737+ i915_read_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x11);
738+ dev_priv->saveGR[0x18] =
739+ i915_read_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x18);
740+
741+ /* Sequencer registers */
742+ for (i = 0; i < 8; i++)
743+ dev_priv->saveSR[i] =
744+ i915_read_indexed(dev, VGA_SR_INDEX, VGA_SR_DATA, i);
745+}
746+
747+static void i915_restore_vga(struct drm_device *dev)
748+{
749+ struct drm_i915_private *dev_priv = dev->dev_private;
750+ int i;
751+ u16 cr_index, cr_data, st01;
752+
753+ /* MSR bits */
754+ I915_WRITE8(VGA_MSR_WRITE, dev_priv->saveMSR);
755+ if (dev_priv->saveMSR & VGA_MSR_CGA_MODE) {
756+ cr_index = VGA_CR_INDEX_CGA;
757+ cr_data = VGA_CR_DATA_CGA;
758+ st01 = VGA_ST01_CGA;
759+ } else {
760+ cr_index = VGA_CR_INDEX_MDA;
761+ cr_data = VGA_CR_DATA_MDA;
762+ st01 = VGA_ST01_MDA;
763+ }
764+
765+ /* Sequencer registers, don't write SR07 */
766+ for (i = 0; i < 7; i++)
767+ i915_write_indexed(dev, VGA_SR_INDEX, VGA_SR_DATA, i,
768+ dev_priv->saveSR[i]);
769+
770+ /* CRT controller regs */
771+ /* Enable CR group 0 writes */
772+ i915_write_indexed(dev, cr_index, cr_data, 0x11, dev_priv->saveCR[0x11]);
773+ for (i = 0; i <= 0x24; i++)
774+ i915_write_indexed(dev, cr_index, cr_data, i, dev_priv->saveCR[i]);
775+
776+ /* Graphics controller regs */
777+ for (i = 0; i < 9; i++)
778+ i915_write_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, i,
779+ dev_priv->saveGR[i]);
780+
781+ i915_write_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x10,
782+ dev_priv->saveGR[0x10]);
783+ i915_write_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x11,
784+ dev_priv->saveGR[0x11]);
785+ i915_write_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x18,
786+ dev_priv->saveGR[0x18]);
787+
788+ /* Attribute controller registers */
789+ I915_READ8(st01); /* switch back to index mode */
790+ for (i = 0; i <= 0x14; i++)
791+ i915_write_ar(dev, st01, i, dev_priv->saveAR[i], 0);
792+ I915_READ8(st01); /* switch back to index mode */
793+ I915_WRITE8(VGA_AR_INDEX, dev_priv->saveAR_INDEX | 0x20);
794+ I915_READ8(st01);
795+
796+ /* VGA color palette registers */
797+ I915_WRITE8(VGA_DACMASK, dev_priv->saveDACMASK);
798+ /* DACCRX automatically increments during read */
799+ I915_WRITE8(VGA_DACWX, 0);
800+ /* Read 3 bytes of color data from each index */
801+ for (i = 0; i < 256 * 3; i++)
802+ I915_WRITE8(VGA_DACDATA, dev_priv->saveDACDATA[i]);
803+
804+}
805+
806+int i915_save_state(struct drm_device *dev)
807+{
808+ struct drm_i915_private *dev_priv = dev->dev_private;
809+ int i;
810+
811+ pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB);
812+
813+ /* Display arbitration control */
814+ dev_priv->saveDSPARB = I915_READ(DSPARB);
815+
816+ /* Pipe & plane A info */
817+ dev_priv->savePIPEACONF = I915_READ(PIPEACONF);
818+ dev_priv->savePIPEASRC = I915_READ(PIPEASRC);
819+ dev_priv->saveFPA0 = I915_READ(FPA0);
820+ dev_priv->saveFPA1 = I915_READ(FPA1);
821+ dev_priv->saveDPLL_A = I915_READ(DPLL_A);
822+ if (IS_I965G(dev))
823+ dev_priv->saveDPLL_A_MD = I915_READ(DPLL_A_MD);
824+ dev_priv->saveHTOTAL_A = I915_READ(HTOTAL_A);
825+ dev_priv->saveHBLANK_A = I915_READ(HBLANK_A);
826+ dev_priv->saveHSYNC_A = I915_READ(HSYNC_A);
827+ dev_priv->saveVTOTAL_A = I915_READ(VTOTAL_A);
828+ dev_priv->saveVBLANK_A = I915_READ(VBLANK_A);
829+ dev_priv->saveVSYNC_A = I915_READ(VSYNC_A);
830+ dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A);
831+
832+ dev_priv->saveDSPACNTR = I915_READ(DSPACNTR);
833+ dev_priv->saveDSPASTRIDE = I915_READ(DSPASTRIDE);
834+ dev_priv->saveDSPASIZE = I915_READ(DSPASIZE);
835+ dev_priv->saveDSPAPOS = I915_READ(DSPAPOS);
836+ dev_priv->saveDSPAADDR = I915_READ(DSPAADDR);
837+ if (IS_I965G(dev)) {
838+ dev_priv->saveDSPASURF = I915_READ(DSPASURF);
839+ dev_priv->saveDSPATILEOFF = I915_READ(DSPATILEOFF);
840+ }
841+ i915_save_palette(dev, PIPE_A);
842+ dev_priv->savePIPEASTAT = I915_READ(PIPEASTAT);
843+
844+ /* Pipe & plane B info */
845+ dev_priv->savePIPEBCONF = I915_READ(PIPEBCONF);
846+ dev_priv->savePIPEBSRC = I915_READ(PIPEBSRC);
847+ dev_priv->saveFPB0 = I915_READ(FPB0);
848+ dev_priv->saveFPB1 = I915_READ(FPB1);
849+ dev_priv->saveDPLL_B = I915_READ(DPLL_B);
850+ if (IS_I965G(dev))
851+ dev_priv->saveDPLL_B_MD = I915_READ(DPLL_B_MD);
852+ dev_priv->saveHTOTAL_B = I915_READ(HTOTAL_B);
853+ dev_priv->saveHBLANK_B = I915_READ(HBLANK_B);
854+ dev_priv->saveHSYNC_B = I915_READ(HSYNC_B);
855+ dev_priv->saveVTOTAL_B = I915_READ(VTOTAL_B);
856+ dev_priv->saveVBLANK_B = I915_READ(VBLANK_B);
857+ dev_priv->saveVSYNC_B = I915_READ(VSYNC_B);
858+ dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A);
859+
860+ dev_priv->saveDSPBCNTR = I915_READ(DSPBCNTR);
861+ dev_priv->saveDSPBSTRIDE = I915_READ(DSPBSTRIDE);
862+ dev_priv->saveDSPBSIZE = I915_READ(DSPBSIZE);
863+ dev_priv->saveDSPBPOS = I915_READ(DSPBPOS);
864+ dev_priv->saveDSPBADDR = I915_READ(DSPBADDR);
865+ if (IS_I965GM(dev) || IS_IGD_GM(dev)) {
866+ dev_priv->saveDSPBSURF = I915_READ(DSPBSURF);
867+ dev_priv->saveDSPBTILEOFF = I915_READ(DSPBTILEOFF);
868+ }
869+ i915_save_palette(dev, PIPE_B);
870+ dev_priv->savePIPEBSTAT = I915_READ(PIPEBSTAT);
871+
872+ /* CRT state */
873+ dev_priv->saveADPA = I915_READ(ADPA);
874+
875+ /* LVDS state */
876+ dev_priv->savePP_CONTROL = I915_READ(PP_CONTROL);
877+ dev_priv->savePFIT_PGM_RATIOS = I915_READ(PFIT_PGM_RATIOS);
878+ dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_CTL);
879+ if (IS_I965G(dev))
880+ dev_priv->saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_CTL2);
881+ if (IS_MOBILE(dev) && !IS_I830(dev))
882+ dev_priv->saveLVDS = I915_READ(LVDS);
883+ if (!IS_I830(dev) && !IS_845G(dev))
884+ dev_priv->savePFIT_CONTROL = I915_READ(PFIT_CONTROL);
885+ dev_priv->savePP_ON_DELAYS = I915_READ(PP_ON_DELAYS);
886+ dev_priv->savePP_OFF_DELAYS = I915_READ(PP_OFF_DELAYS);
887+ dev_priv->savePP_DIVISOR = I915_READ(PP_DIVISOR);
888+
889+ /* FIXME: save TV & SDVO state */
890+
891+ /* FBC state */
892+ dev_priv->saveFBC_CFB_BASE = I915_READ(FBC_CFB_BASE);
893+ dev_priv->saveFBC_LL_BASE = I915_READ(FBC_LL_BASE);
894+ dev_priv->saveFBC_CONTROL2 = I915_READ(FBC_CONTROL2);
895+ dev_priv->saveFBC_CONTROL = I915_READ(FBC_CONTROL);
896+
897+ /* Interrupt state */
898+ dev_priv->saveIIR = I915_READ(IIR);
899+ dev_priv->saveIER = I915_READ(IER);
900+ dev_priv->saveIMR = I915_READ(IMR);
901+
902+ /* VGA state */
903+ dev_priv->saveVGA0 = I915_READ(VGA0);
904+ dev_priv->saveVGA1 = I915_READ(VGA1);
905+ dev_priv->saveVGA_PD = I915_READ(VGA_PD);
906+ dev_priv->saveVGACNTRL = I915_READ(VGACNTRL);
907+
908+ /* Clock gating state */
909+ dev_priv->saveD_STATE = I915_READ(D_STATE);
910+ dev_priv->saveCG_2D_DIS = I915_READ(CG_2D_DIS);
911+
912+ /* Cache mode state */
913+ dev_priv->saveCACHE_MODE_0 = I915_READ(CACHE_MODE_0);
914+
915+ /* Memory Arbitration state */
916+ dev_priv->saveMI_ARB_STATE = I915_READ(MI_ARB_STATE);
917+
918+ /* Scratch space */
919+ for (i = 0; i < 16; i++) {
920+ dev_priv->saveSWF0[i] = I915_READ(SWF00 + (i << 2));
921+ dev_priv->saveSWF1[i] = I915_READ(SWF10 + (i << 2));
922+ }
923+ for (i = 0; i < 3; i++)
924+ dev_priv->saveSWF2[i] = I915_READ(SWF30 + (i << 2));
925+
926+ i915_save_vga(dev);
927+
928+ return 0;
929+}
930+
931+int i915_restore_state(struct drm_device *dev)
932+{
933+ struct drm_i915_private *dev_priv = dev->dev_private;
934+ int i;
935+
936+ pci_write_config_byte(dev->pdev, LBB, dev_priv->saveLBB);
937+
938+ I915_WRITE(DSPARB, dev_priv->saveDSPARB);
939+
940+ /* Pipe & plane A info */
941+ /* Prime the clock */
942+ if (dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) {
943+ I915_WRITE(DPLL_A, dev_priv->saveDPLL_A &
944+ ~DPLL_VCO_ENABLE);
945+ DRM_UDELAY(150);
946+ }
947+ I915_WRITE(FPA0, dev_priv->saveFPA0);
948+ I915_WRITE(FPA1, dev_priv->saveFPA1);
949+ /* Actually enable it */
950+ I915_WRITE(DPLL_A, dev_priv->saveDPLL_A);
951+ DRM_UDELAY(150);
952+ if (IS_I965G(dev))
953+ I915_WRITE(DPLL_A_MD, dev_priv->saveDPLL_A_MD);
954+ DRM_UDELAY(150);
955+
956+ /* Restore mode */
957+ I915_WRITE(HTOTAL_A, dev_priv->saveHTOTAL_A);
958+ I915_WRITE(HBLANK_A, dev_priv->saveHBLANK_A);
959+ I915_WRITE(HSYNC_A, dev_priv->saveHSYNC_A);
960+ I915_WRITE(VTOTAL_A, dev_priv->saveVTOTAL_A);
961+ I915_WRITE(VBLANK_A, dev_priv->saveVBLANK_A);
962+ I915_WRITE(VSYNC_A, dev_priv->saveVSYNC_A);
963+ I915_WRITE(BCLRPAT_A, dev_priv->saveBCLRPAT_A);
964+
965+ /* Restore plane info */
966+ I915_WRITE(DSPASIZE, dev_priv->saveDSPASIZE);
967+ I915_WRITE(DSPAPOS, dev_priv->saveDSPAPOS);
968+ I915_WRITE(PIPEASRC, dev_priv->savePIPEASRC);
969+ I915_WRITE(DSPAADDR, dev_priv->saveDSPAADDR);
970+ I915_WRITE(DSPASTRIDE, dev_priv->saveDSPASTRIDE);
971+ if (IS_I965G(dev)) {
972+ I915_WRITE(DSPASURF, dev_priv->saveDSPASURF);
973+ I915_WRITE(DSPATILEOFF, dev_priv->saveDSPATILEOFF);
974+ }
975+
976+ I915_WRITE(PIPEACONF, dev_priv->savePIPEACONF);
977+
978+ i915_restore_palette(dev, PIPE_A);
979+ /* Enable the plane */
980+ I915_WRITE(DSPACNTR, dev_priv->saveDSPACNTR);
981+ I915_WRITE(DSPAADDR, I915_READ(DSPAADDR));
982+
983+ /* Pipe & plane B info */
984+ if (dev_priv->saveDPLL_B & DPLL_VCO_ENABLE) {
985+ I915_WRITE(DPLL_B, dev_priv->saveDPLL_B &
986+ ~DPLL_VCO_ENABLE);
987+ DRM_UDELAY(150);
988+ }
989+ I915_WRITE(FPB0, dev_priv->saveFPB0);
990+ I915_WRITE(FPB1, dev_priv->saveFPB1);
991+ /* Actually enable it */
992+ I915_WRITE(DPLL_B, dev_priv->saveDPLL_B);
993+ DRM_UDELAY(150);
994+ if (IS_I965G(dev))
995+ I915_WRITE(DPLL_B_MD, dev_priv->saveDPLL_B_MD);
996+ DRM_UDELAY(150);
997+
998+ /* Restore mode */
999+ I915_WRITE(HTOTAL_B, dev_priv->saveHTOTAL_B);
1000+ I915_WRITE(HBLANK_B, dev_priv->saveHBLANK_B);
1001+ I915_WRITE(HSYNC_B, dev_priv->saveHSYNC_B);
1002+ I915_WRITE(VTOTAL_B, dev_priv->saveVTOTAL_B);
1003+ I915_WRITE(VBLANK_B, dev_priv->saveVBLANK_B);
1004+ I915_WRITE(VSYNC_B, dev_priv->saveVSYNC_B);
1005+ I915_WRITE(BCLRPAT_B, dev_priv->saveBCLRPAT_B);
1006+
1007+ /* Restore plane info */
1008+ I915_WRITE(DSPBSIZE, dev_priv->saveDSPBSIZE);
1009+ I915_WRITE(DSPBPOS, dev_priv->saveDSPBPOS);
1010+ I915_WRITE(PIPEBSRC, dev_priv->savePIPEBSRC);
1011+ I915_WRITE(DSPBADDR, dev_priv->saveDSPBADDR);
1012+ I915_WRITE(DSPBSTRIDE, dev_priv->saveDSPBSTRIDE);
1013+ if (IS_I965G(dev)) {
1014+ I915_WRITE(DSPBSURF, dev_priv->saveDSPBSURF);
1015+ I915_WRITE(DSPBTILEOFF, dev_priv->saveDSPBTILEOFF);
1016+ }
1017+
1018+ I915_WRITE(PIPEBCONF, dev_priv->savePIPEBCONF);
1019+
1020+ i915_restore_palette(dev, PIPE_B);
1021+ /* Enable the plane */
1022+ I915_WRITE(DSPBCNTR, dev_priv->saveDSPBCNTR);
1023+ I915_WRITE(DSPBADDR, I915_READ(DSPBADDR));
1024+
1025+ /* CRT state */
1026+ I915_WRITE(ADPA, dev_priv->saveADPA);
1027+
1028+ /* LVDS state */
1029+ if (IS_I965G(dev))
1030+ I915_WRITE(BLC_PWM_CTL2, dev_priv->saveBLC_PWM_CTL2);
1031+ if (IS_MOBILE(dev) && !IS_I830(dev))
1032+ I915_WRITE(LVDS, dev_priv->saveLVDS);
1033+ if (!IS_I830(dev) && !IS_845G(dev))
1034+ I915_WRITE(PFIT_CONTROL, dev_priv->savePFIT_CONTROL);
1035+
1036+ I915_WRITE(PFIT_PGM_RATIOS, dev_priv->savePFIT_PGM_RATIOS);
1037+ I915_WRITE(BLC_PWM_CTL, dev_priv->saveBLC_PWM_CTL);
1038+ I915_WRITE(PP_ON_DELAYS, dev_priv->savePP_ON_DELAYS);
1039+ I915_WRITE(PP_OFF_DELAYS, dev_priv->savePP_OFF_DELAYS);
1040+ I915_WRITE(PP_DIVISOR, dev_priv->savePP_DIVISOR);
1041+ I915_WRITE(PP_CONTROL, dev_priv->savePP_CONTROL);
1042+
1043+ /* FIXME: restore TV & SDVO state */
1044+
1045+ /* FBC info */
1046+ I915_WRITE(FBC_CFB_BASE, dev_priv->saveFBC_CFB_BASE);
1047+ I915_WRITE(FBC_LL_BASE, dev_priv->saveFBC_LL_BASE);
1048+ I915_WRITE(FBC_CONTROL2, dev_priv->saveFBC_CONTROL2);
1049+ I915_WRITE(FBC_CONTROL, dev_priv->saveFBC_CONTROL);
1050+
1051+ /* VGA state */
1052+ I915_WRITE(VGACNTRL, dev_priv->saveVGACNTRL);
1053+ I915_WRITE(VGA0, dev_priv->saveVGA0);
1054+ I915_WRITE(VGA1, dev_priv->saveVGA1);
1055+ I915_WRITE(VGA_PD, dev_priv->saveVGA_PD);
1056+ DRM_UDELAY(150);
1057+
1058+ /* Clock gating state */
1059+ I915_WRITE (D_STATE, dev_priv->saveD_STATE);
1060+ I915_WRITE (CG_2D_DIS, dev_priv->saveCG_2D_DIS);
1061+
1062+ /* Cache mode state */
1063+ I915_WRITE (CACHE_MODE_0, dev_priv->saveCACHE_MODE_0 | 0xffff0000);
1064+
1065+ /* Memory arbitration state */
1066+ I915_WRITE (MI_ARB_STATE, dev_priv->saveMI_ARB_STATE | 0xffff0000);
1067+
1068+ for (i = 0; i < 16; i++) {
1069+ I915_WRITE(SWF00 + (i << 2), dev_priv->saveSWF0[i]);
1070+ I915_WRITE(SWF10 + (i << 2), dev_priv->saveSWF1[i+7]);
1071+ }
1072+ for (i = 0; i < 3; i++)
1073+ I915_WRITE(SWF30 + (i << 2), dev_priv->saveSWF2[i]);
1074+
1075+ i915_restore_vga(dev);
1076+
1077+ return 0;
1078+}
1079+
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0011-drm-vblank-rework.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0011-drm-vblank-rework.patch
new file mode 100644
index 0000000000..6161a71f04
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0011-drm-vblank-rework.patch
@@ -0,0 +1,1534 @@
1commit 2aebb4e4e62d09b4a95be7be7c24a7f6528385b7
2Author: Jesse Barnes <jbarnes@virtuousgeek.org>
3Date: Tue Sep 30 12:14:26 2008 -0700
4
5 drm: Rework vblank-wait handling to allow interrupt reduction.
6
7 Previously, drivers supporting vblank interrupt waits would run the interrupt
8 all the time, or all the time that any 3d client was running, preventing the
9 CPU from sleeping for long when the system was otherwise idle. Now, interrupts
10 are disabled any time that no client is waiting on a vblank event. The new
11 method uses vblank counters on the chipsets when the interrupts are turned
12 off, rather than counting interrupts, so that we can continue to present
13 accurate vblank numbers.
14
15 Co-author: Michel Dänzer <michel@tungstengraphics.com>
16 Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
17 Signed-off-by: Eric Anholt <eric@anholt.net>
18 Signed-off-by: Dave Airlie <airlied@redhat.com>
19
20diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
21index 452c2d8..fb45fe7 100644
22--- a/drivers/gpu/drm/drm_drv.c
23+++ b/drivers/gpu/drm/drm_drv.c
24@@ -116,6 +116,8 @@ static struct drm_ioctl_desc drm_ioctls[] = {
25
26 DRM_IOCTL_DEF(DRM_IOCTL_WAIT_VBLANK, drm_wait_vblank, 0),
27
28+ DRM_IOCTL_DEF(DRM_IOCTL_MODESET_CTL, drm_modeset_ctl, 0),
29+
30 DRM_IOCTL_DEF(DRM_IOCTL_UPDATE_DRAW, drm_update_drawable_info, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
31 };
32
33diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
34index 61ed515..d0c13d9 100644
35--- a/drivers/gpu/drm/drm_irq.c
36+++ b/drivers/gpu/drm/drm_irq.c
37@@ -71,19 +71,131 @@ int drm_irq_by_busid(struct drm_device *dev, void *data,
38 return 0;
39 }
40
41+static void vblank_disable_fn(unsigned long arg)
42+{
43+ struct drm_device *dev = (struct drm_device *)arg;
44+ unsigned long irqflags;
45+ int i;
46+
47+ if (!dev->vblank_disable_allowed)
48+ return;
49+
50+ for (i = 0; i < dev->num_crtcs; i++) {
51+ spin_lock_irqsave(&dev->vbl_lock, irqflags);
52+ if (atomic_read(&dev->vblank_refcount[i]) == 0 &&
53+ dev->vblank_enabled[i]) {
54+ DRM_DEBUG("disabling vblank on crtc %d\n", i);
55+ dev->last_vblank[i] =
56+ dev->driver->get_vblank_counter(dev, i);
57+ dev->driver->disable_vblank(dev, i);
58+ dev->vblank_enabled[i] = 0;
59+ }
60+ spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
61+ }
62+}
63+
64+static void drm_vblank_cleanup(struct drm_device *dev)
65+{
66+ /* Bail if the driver didn't call drm_vblank_init() */
67+ if (dev->num_crtcs == 0)
68+ return;
69+
70+ del_timer(&dev->vblank_disable_timer);
71+
72+ vblank_disable_fn((unsigned long)dev);
73+
74+ drm_free(dev->vbl_queue, sizeof(*dev->vbl_queue) * dev->num_crtcs,
75+ DRM_MEM_DRIVER);
76+ drm_free(dev->vbl_sigs, sizeof(*dev->vbl_sigs) * dev->num_crtcs,
77+ DRM_MEM_DRIVER);
78+ drm_free(dev->_vblank_count, sizeof(*dev->_vblank_count) *
79+ dev->num_crtcs, DRM_MEM_DRIVER);
80+ drm_free(dev->vblank_refcount, sizeof(*dev->vblank_refcount) *
81+ dev->num_crtcs, DRM_MEM_DRIVER);
82+ drm_free(dev->vblank_enabled, sizeof(*dev->vblank_enabled) *
83+ dev->num_crtcs, DRM_MEM_DRIVER);
84+ drm_free(dev->last_vblank, sizeof(*dev->last_vblank) * dev->num_crtcs,
85+ DRM_MEM_DRIVER);
86+ drm_free(dev->vblank_inmodeset, sizeof(*dev->vblank_inmodeset) *
87+ dev->num_crtcs, DRM_MEM_DRIVER);
88+
89+ dev->num_crtcs = 0;
90+}
91+
92+int drm_vblank_init(struct drm_device *dev, int num_crtcs)
93+{
94+ int i, ret = -ENOMEM;
95+
96+ setup_timer(&dev->vblank_disable_timer, vblank_disable_fn,
97+ (unsigned long)dev);
98+ spin_lock_init(&dev->vbl_lock);
99+ atomic_set(&dev->vbl_signal_pending, 0);
100+ dev->num_crtcs = num_crtcs;
101+
102+ dev->vbl_queue = drm_alloc(sizeof(wait_queue_head_t) * num_crtcs,
103+ DRM_MEM_DRIVER);
104+ if (!dev->vbl_queue)
105+ goto err;
106+
107+ dev->vbl_sigs = drm_alloc(sizeof(struct list_head) * num_crtcs,
108+ DRM_MEM_DRIVER);
109+ if (!dev->vbl_sigs)
110+ goto err;
111+
112+ dev->_vblank_count = drm_alloc(sizeof(atomic_t) * num_crtcs,
113+ DRM_MEM_DRIVER);
114+ if (!dev->_vblank_count)
115+ goto err;
116+
117+ dev->vblank_refcount = drm_alloc(sizeof(atomic_t) * num_crtcs,
118+ DRM_MEM_DRIVER);
119+ if (!dev->vblank_refcount)
120+ goto err;
121+
122+ dev->vblank_enabled = drm_calloc(num_crtcs, sizeof(int),
123+ DRM_MEM_DRIVER);
124+ if (!dev->vblank_enabled)
125+ goto err;
126+
127+ dev->last_vblank = drm_calloc(num_crtcs, sizeof(u32), DRM_MEM_DRIVER);
128+ if (!dev->last_vblank)
129+ goto err;
130+
131+ dev->vblank_inmodeset = drm_calloc(num_crtcs, sizeof(int),
132+ DRM_MEM_DRIVER);
133+ if (!dev->vblank_inmodeset)
134+ goto err;
135+
136+ /* Zero per-crtc vblank stuff */
137+ for (i = 0; i < num_crtcs; i++) {
138+ init_waitqueue_head(&dev->vbl_queue[i]);
139+ INIT_LIST_HEAD(&dev->vbl_sigs[i]);
140+ atomic_set(&dev->_vblank_count[i], 0);
141+ atomic_set(&dev->vblank_refcount[i], 0);
142+ }
143+
144+ dev->vblank_disable_allowed = 0;
145+
146+ return 0;
147+
148+err:
149+ drm_vblank_cleanup(dev);
150+ return ret;
151+}
152+EXPORT_SYMBOL(drm_vblank_init);
153+
154 /**
155 * Install IRQ handler.
156 *
157 * \param dev DRM device.
158- * \param irq IRQ number.
159 *
160- * Initializes the IRQ related data, and setups drm_device::vbl_queue. Installs the handler, calling the driver
161+ * Initializes the IRQ related data. Installs the handler, calling the driver
162 * \c drm_driver_irq_preinstall() and \c drm_driver_irq_postinstall() functions
163 * before and after the installation.
164 */
165-static int drm_irq_install(struct drm_device * dev)
166+int drm_irq_install(struct drm_device *dev)
167 {
168- int ret;
169+ int ret = 0;
170 unsigned long sh_flags = 0;
171
172 if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
173@@ -109,17 +221,6 @@ static int drm_irq_install(struct drm_device * dev)
174
175 DRM_DEBUG("irq=%d\n", dev->pdev->irq);
176
177- if (drm_core_check_feature(dev, DRIVER_IRQ_VBL)) {
178- init_waitqueue_head(&dev->vbl_queue);
179-
180- spin_lock_init(&dev->vbl_lock);
181-
182- INIT_LIST_HEAD(&dev->vbl_sigs);
183- INIT_LIST_HEAD(&dev->vbl_sigs2);
184-
185- dev->vbl_pending = 0;
186- }
187-
188 /* Before installing handler */
189 dev->driver->irq_preinstall(dev);
190
191@@ -141,10 +242,16 @@ static int drm_irq_install(struct drm_device * dev)
192 }
193
194 /* After installing handler */
195- dev->driver->irq_postinstall(dev);
196+ ret = dev->driver->irq_postinstall(dev);
197+ if (ret < 0) {
198+ mutex_lock(&dev->struct_mutex);
199+ dev->irq_enabled = 0;
200+ mutex_unlock(&dev->struct_mutex);
201+ }
202
203- return 0;
204+ return ret;
205 }
206+EXPORT_SYMBOL(drm_irq_install);
207
208 /**
209 * Uninstall the IRQ handler.
210@@ -174,11 +281,12 @@ int drm_irq_uninstall(struct drm_device * dev)
211
212 free_irq(dev->pdev->irq, dev);
213
214+ drm_vblank_cleanup(dev);
215+
216 dev->locked_tasklet_func = NULL;
217
218 return 0;
219 }
220-
221 EXPORT_SYMBOL(drm_irq_uninstall);
222
223 /**
224@@ -218,6 +326,174 @@ int drm_control(struct drm_device *dev, void *data,
225 }
226
227 /**
228+ * drm_vblank_count - retrieve "cooked" vblank counter value
229+ * @dev: DRM device
230+ * @crtc: which counter to retrieve
231+ *
232+ * Fetches the "cooked" vblank count value that represents the number of
233+ * vblank events since the system was booted, including lost events due to
234+ * modesetting activity.
235+ */
236+u32 drm_vblank_count(struct drm_device *dev, int crtc)
237+{
238+ return atomic_read(&dev->_vblank_count[crtc]);
239+}
240+EXPORT_SYMBOL(drm_vblank_count);
241+
242+/**
243+ * drm_update_vblank_count - update the master vblank counter
244+ * @dev: DRM device
245+ * @crtc: counter to update
246+ *
247+ * Call back into the driver to update the appropriate vblank counter
248+ * (specified by @crtc). Deal with wraparound, if it occurred, and
249+ * update the last read value so we can deal with wraparound on the next
250+ * call if necessary.
251+ *
252+ * Only necessary when going from off->on, to account for frames we
253+ * didn't get an interrupt for.
254+ *
255+ * Note: caller must hold dev->vbl_lock since this reads & writes
256+ * device vblank fields.
257+ */
258+static void drm_update_vblank_count(struct drm_device *dev, int crtc)
259+{
260+ u32 cur_vblank, diff;
261+
262+ /*
263+ * Interrupts were disabled prior to this call, so deal with counter
264+ * wrap if needed.
265+ * NOTE! It's possible we lost a full dev->max_vblank_count events
266+ * here if the register is small or we had vblank interrupts off for
267+ * a long time.
268+ */
269+ cur_vblank = dev->driver->get_vblank_counter(dev, crtc);
270+ diff = cur_vblank - dev->last_vblank[crtc];
271+ if (cur_vblank < dev->last_vblank[crtc]) {
272+ diff += dev->max_vblank_count;
273+
274+ DRM_DEBUG("last_vblank[%d]=0x%x, cur_vblank=0x%x => diff=0x%x\n",
275+ crtc, dev->last_vblank[crtc], cur_vblank, diff);
276+ }
277+
278+ DRM_DEBUG("enabling vblank interrupts on crtc %d, missed %d\n",
279+ crtc, diff);
280+
281+ atomic_add(diff, &dev->_vblank_count[crtc]);
282+}
283+
284+/**
285+ * drm_vblank_get - get a reference count on vblank events
286+ * @dev: DRM device
287+ * @crtc: which CRTC to own
288+ *
289+ * Acquire a reference count on vblank events to avoid having them disabled
290+ * while in use.
291+ *
292+ * RETURNS
293+ * Zero on success, nonzero on failure.
294+ */
295+int drm_vblank_get(struct drm_device *dev, int crtc)
296+{
297+ unsigned long irqflags;
298+ int ret = 0;
299+
300+ spin_lock_irqsave(&dev->vbl_lock, irqflags);
301+ /* Going from 0->1 means we have to enable interrupts again */
302+ if (atomic_add_return(1, &dev->vblank_refcount[crtc]) == 1 &&
303+ !dev->vblank_enabled[crtc]) {
304+ ret = dev->driver->enable_vblank(dev, crtc);
305+ DRM_DEBUG("enabling vblank on crtc %d, ret: %d\n", crtc, ret);
306+ if (ret)
307+ atomic_dec(&dev->vblank_refcount[crtc]);
308+ else {
309+ dev->vblank_enabled[crtc] = 1;
310+ drm_update_vblank_count(dev, crtc);
311+ }
312+ }
313+ spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
314+
315+ return ret;
316+}
317+EXPORT_SYMBOL(drm_vblank_get);
318+
319+/**
320+ * drm_vblank_put - give up ownership of vblank events
321+ * @dev: DRM device
322+ * @crtc: which counter to give up
323+ *
324+ * Release ownership of a given vblank counter, turning off interrupts
325+ * if possible.
326+ */
327+void drm_vblank_put(struct drm_device *dev, int crtc)
328+{
329+ /* Last user schedules interrupt disable */
330+ if (atomic_dec_and_test(&dev->vblank_refcount[crtc]))
331+ mod_timer(&dev->vblank_disable_timer, jiffies + 5*DRM_HZ);
332+}
333+EXPORT_SYMBOL(drm_vblank_put);
334+
335+/**
336+ * drm_modeset_ctl - handle vblank event counter changes across mode switch
337+ * @DRM_IOCTL_ARGS: standard ioctl arguments
338+ *
339+ * Applications should call the %_DRM_PRE_MODESET and %_DRM_POST_MODESET
340+ * ioctls around modesetting so that any lost vblank events are accounted for.
341+ *
342+ * Generally the counter will reset across mode sets. If interrupts are
343+ * enabled around this call, we don't have to do anything since the counter
344+ * will have already been incremented.
345+ */
346+int drm_modeset_ctl(struct drm_device *dev, void *data,
347+ struct drm_file *file_priv)
348+{
349+ struct drm_modeset_ctl *modeset = data;
350+ unsigned long irqflags;
351+ int crtc, ret = 0;
352+
353+ /* If drm_vblank_init() hasn't been called yet, just no-op */
354+ if (!dev->num_crtcs)
355+ goto out;
356+
357+ crtc = modeset->crtc;
358+ if (crtc >= dev->num_crtcs) {
359+ ret = -EINVAL;
360+ goto out;
361+ }
362+
363+ /*
364+ * To avoid all the problems that might happen if interrupts
365+ * were enabled/disabled around or between these calls, we just
366+ * have the kernel take a reference on the CRTC (just once though
367+ * to avoid corrupting the count if multiple, mismatch calls occur),
368+ * so that interrupts remain enabled in the interim.
369+ */
370+ switch (modeset->cmd) {
371+ case _DRM_PRE_MODESET:
372+ if (!dev->vblank_inmodeset[crtc]) {
373+ dev->vblank_inmodeset[crtc] = 1;
374+ drm_vblank_get(dev, crtc);
375+ }
376+ break;
377+ case _DRM_POST_MODESET:
378+ if (dev->vblank_inmodeset[crtc]) {
379+ spin_lock_irqsave(&dev->vbl_lock, irqflags);
380+ dev->vblank_disable_allowed = 1;
381+ dev->vblank_inmodeset[crtc] = 0;
382+ spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
383+ drm_vblank_put(dev, crtc);
384+ }
385+ break;
386+ default:
387+ ret = -EINVAL;
388+ break;
389+ }
390+
391+out:
392+ return ret;
393+}
394+
395+/**
396 * Wait for VBLANK.
397 *
398 * \param inode device inode.
399@@ -236,12 +512,12 @@ int drm_control(struct drm_device *dev, void *data,
400 *
401 * If a signal is not requested, then calls vblank_wait().
402 */
403-int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_priv)
404+int drm_wait_vblank(struct drm_device *dev, void *data,
405+ struct drm_file *file_priv)
406 {
407 union drm_wait_vblank *vblwait = data;
408- struct timeval now;
409 int ret = 0;
410- unsigned int flags, seq;
411+ unsigned int flags, seq, crtc;
412
413 if ((!dev->pdev->irq) || (!dev->irq_enabled))
414 return -EINVAL;
415@@ -255,13 +531,17 @@ int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_pr
416 }
417
418 flags = vblwait->request.type & _DRM_VBLANK_FLAGS_MASK;
419+ crtc = flags & _DRM_VBLANK_SECONDARY ? 1 : 0;
420
421- if (!drm_core_check_feature(dev, (flags & _DRM_VBLANK_SECONDARY) ?
422- DRIVER_IRQ_VBL2 : DRIVER_IRQ_VBL))
423+ if (crtc >= dev->num_crtcs)
424 return -EINVAL;
425
426- seq = atomic_read((flags & _DRM_VBLANK_SECONDARY) ? &dev->vbl_received2
427- : &dev->vbl_received);
428+ ret = drm_vblank_get(dev, crtc);
429+ if (ret) {
430+ DRM_ERROR("failed to acquire vblank counter, %d\n", ret);
431+ return ret;
432+ }
433+ seq = drm_vblank_count(dev, crtc);
434
435 switch (vblwait->request.type & _DRM_VBLANK_TYPES_MASK) {
436 case _DRM_VBLANK_RELATIVE:
437@@ -270,7 +550,8 @@ int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_pr
438 case _DRM_VBLANK_ABSOLUTE:
439 break;
440 default:
441- return -EINVAL;
442+ ret = -EINVAL;
443+ goto done;
444 }
445
446 if ((flags & _DRM_VBLANK_NEXTONMISS) &&
447@@ -280,8 +561,7 @@ int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_pr
448
449 if (flags & _DRM_VBLANK_SIGNAL) {
450 unsigned long irqflags;
451- struct list_head *vbl_sigs = (flags & _DRM_VBLANK_SECONDARY)
452- ? &dev->vbl_sigs2 : &dev->vbl_sigs;
453+ struct list_head *vbl_sigs = &dev->vbl_sigs[crtc];
454 struct drm_vbl_sig *vbl_sig;
455
456 spin_lock_irqsave(&dev->vbl_lock, irqflags);
457@@ -302,22 +582,29 @@ int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_pr
458 }
459 }
460
461- if (dev->vbl_pending >= 100) {
462+ if (atomic_read(&dev->vbl_signal_pending) >= 100) {
463 spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
464- return -EBUSY;
465+ ret = -EBUSY;
466+ goto done;
467 }
468
469- dev->vbl_pending++;
470-
471 spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
472
473- if (!
474- (vbl_sig =
475- drm_alloc(sizeof(struct drm_vbl_sig), DRM_MEM_DRIVER))) {
476- return -ENOMEM;
477+ vbl_sig = drm_calloc(1, sizeof(struct drm_vbl_sig),
478+ DRM_MEM_DRIVER);
479+ if (!vbl_sig) {
480+ ret = -ENOMEM;
481+ goto done;
482+ }
483+
484+ ret = drm_vblank_get(dev, crtc);
485+ if (ret) {
486+ drm_free(vbl_sig, sizeof(struct drm_vbl_sig),
487+ DRM_MEM_DRIVER);
488+ return ret;
489 }
490
491- memset((void *)vbl_sig, 0, sizeof(*vbl_sig));
492+ atomic_inc(&dev->vbl_signal_pending);
493
494 vbl_sig->sequence = vblwait->request.sequence;
495 vbl_sig->info.si_signo = vblwait->request.signal;
496@@ -331,20 +618,29 @@ int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_pr
497
498 vblwait->reply.sequence = seq;
499 } else {
500- if (flags & _DRM_VBLANK_SECONDARY) {
501- if (dev->driver->vblank_wait2)
502- ret = dev->driver->vblank_wait2(dev, &vblwait->request.sequence);
503- } else if (dev->driver->vblank_wait)
504- ret =
505- dev->driver->vblank_wait(dev,
506- &vblwait->request.sequence);
507-
508- do_gettimeofday(&now);
509- vblwait->reply.tval_sec = now.tv_sec;
510- vblwait->reply.tval_usec = now.tv_usec;
511+ DRM_DEBUG("waiting on vblank count %d, crtc %d\n",
512+ vblwait->request.sequence, crtc);
513+ DRM_WAIT_ON(ret, dev->vbl_queue[crtc], 3 * DRM_HZ,
514+ ((drm_vblank_count(dev, crtc)
515+ - vblwait->request.sequence) <= (1 << 23)));
516+
517+ if (ret != -EINTR) {
518+ struct timeval now;
519+
520+ do_gettimeofday(&now);
521+
522+ vblwait->reply.tval_sec = now.tv_sec;
523+ vblwait->reply.tval_usec = now.tv_usec;
524+ vblwait->reply.sequence = drm_vblank_count(dev, crtc);
525+ DRM_DEBUG("returning %d to client\n",
526+ vblwait->reply.sequence);
527+ } else {
528+ DRM_DEBUG("vblank wait interrupted by signal\n");
529+ }
530 }
531
532- done:
533+done:
534+ drm_vblank_put(dev, crtc);
535 return ret;
536 }
537
538@@ -352,44 +648,57 @@ int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_pr
539 * Send the VBLANK signals.
540 *
541 * \param dev DRM device.
542+ * \param crtc CRTC where the vblank event occurred
543 *
544 * Sends a signal for each task in drm_device::vbl_sigs and empties the list.
545 *
546 * If a signal is not requested, then calls vblank_wait().
547 */
548-void drm_vbl_send_signals(struct drm_device * dev)
549+static void drm_vbl_send_signals(struct drm_device *dev, int crtc)
550 {
551+ struct drm_vbl_sig *vbl_sig, *tmp;
552+ struct list_head *vbl_sigs;
553+ unsigned int vbl_seq;
554 unsigned long flags;
555- int i;
556
557 spin_lock_irqsave(&dev->vbl_lock, flags);
558
559- for (i = 0; i < 2; i++) {
560- struct drm_vbl_sig *vbl_sig, *tmp;
561- struct list_head *vbl_sigs = i ? &dev->vbl_sigs2 : &dev->vbl_sigs;
562- unsigned int vbl_seq = atomic_read(i ? &dev->vbl_received2 :
563- &dev->vbl_received);
564+ vbl_sigs = &dev->vbl_sigs[crtc];
565+ vbl_seq = drm_vblank_count(dev, crtc);
566
567- list_for_each_entry_safe(vbl_sig, tmp, vbl_sigs, head) {
568- if ((vbl_seq - vbl_sig->sequence) <= (1 << 23)) {
569- vbl_sig->info.si_code = vbl_seq;
570- send_sig_info(vbl_sig->info.si_signo,
571- &vbl_sig->info, vbl_sig->task);
572+ list_for_each_entry_safe(vbl_sig, tmp, vbl_sigs, head) {
573+ if ((vbl_seq - vbl_sig->sequence) <= (1 << 23)) {
574+ vbl_sig->info.si_code = vbl_seq;
575+ send_sig_info(vbl_sig->info.si_signo,
576+ &vbl_sig->info, vbl_sig->task);
577
578- list_del(&vbl_sig->head);
579-
580- drm_free(vbl_sig, sizeof(*vbl_sig),
581- DRM_MEM_DRIVER);
582+ list_del(&vbl_sig->head);
583
584- dev->vbl_pending--;
585- }
586- }
587+ drm_free(vbl_sig, sizeof(*vbl_sig),
588+ DRM_MEM_DRIVER);
589+ atomic_dec(&dev->vbl_signal_pending);
590+ drm_vblank_put(dev, crtc);
591+ }
592 }
593
594 spin_unlock_irqrestore(&dev->vbl_lock, flags);
595 }
596
597-EXPORT_SYMBOL(drm_vbl_send_signals);
598+/**
599+ * drm_handle_vblank - handle a vblank event
600+ * @dev: DRM device
601+ * @crtc: where this event occurred
602+ *
603+ * Drivers should call this routine in their vblank interrupt handlers to
604+ * update the vblank counter and send any signals that may be pending.
605+ */
606+void drm_handle_vblank(struct drm_device *dev, int crtc)
607+{
608+ atomic_inc(&dev->_vblank_count[crtc]);
609+ DRM_WAKEUP(&dev->vbl_queue[crtc]);
610+ drm_vbl_send_signals(dev, crtc);
611+}
612+EXPORT_SYMBOL(drm_handle_vblank);
613
614 /**
615 * Tasklet wrapper function.
616diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
617index cead62f..8609ec2 100644
618--- a/drivers/gpu/drm/i915/i915_dma.c
619+++ b/drivers/gpu/drm/i915/i915_dma.c
620@@ -673,7 +673,7 @@ static int i915_getparam(struct drm_device *dev, void *data,
621
622 switch (param->param) {
623 case I915_PARAM_IRQ_ACTIVE:
624- value = dev->irq_enabled;
625+ value = dev->pdev->irq ? 1 : 0;
626 break;
627 case I915_PARAM_ALLOW_BATCHBUFFER:
628 value = dev_priv->allow_batchbuffer ? 1 : 0;
629@@ -808,7 +808,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
630 * and the registers being closely associated.
631 */
632 if (!IS_I945G(dev) && !IS_I945GM(dev))
633- pci_enable_msi(dev->pdev);
634+ if (pci_enable_msi(dev->pdev))
635+ DRM_ERROR("failed to enable MSI\n");
636
637 intel_opregion_init(dev);
638
639diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
640index eff66ed..37af03f 100644
641--- a/drivers/gpu/drm/i915/i915_drv.c
642+++ b/drivers/gpu/drm/i915/i915_drv.c
643@@ -85,10 +85,8 @@ static struct drm_driver driver = {
644 /* don't use mtrr's here, the Xserver or user space app should
645 * deal with them for intel hardware.
646 */
647- .driver_features =
648- DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | /* DRIVER_USE_MTRR |*/
649- DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL |
650- DRIVER_IRQ_VBL2,
651+ .driver_features = DRIVER_USE_AGP | DRIVER_REQUIRE_AGP |
652+ DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED,
653 .load = i915_driver_load,
654 .unload = i915_driver_unload,
655 .lastclose = i915_driver_lastclose,
656@@ -96,8 +94,9 @@ static struct drm_driver driver = {
657 .suspend = i915_suspend,
658 .resume = i915_resume,
659 .device_is_agp = i915_driver_device_is_agp,
660- .vblank_wait = i915_driver_vblank_wait,
661- .vblank_wait2 = i915_driver_vblank_wait2,
662+ .get_vblank_counter = i915_get_vblank_counter,
663+ .enable_vblank = i915_enable_vblank,
664+ .disable_vblank = i915_disable_vblank,
665 .irq_preinstall = i915_driver_irq_preinstall,
666 .irq_postinstall = i915_driver_irq_postinstall,
667 .irq_uninstall = i915_driver_irq_uninstall,
668diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
669index 71326ca..d1a02be 100644
670--- a/drivers/gpu/drm/i915/i915_drv.h
671+++ b/drivers/gpu/drm/i915/i915_drv.h
672@@ -83,10 +83,15 @@ struct mem_block {
673 typedef struct _drm_i915_vbl_swap {
674 struct list_head head;
675 drm_drawable_t drw_id;
676- unsigned int pipe;
677+ unsigned int plane;
678 unsigned int sequence;
679 } drm_i915_vbl_swap_t;
680
681+struct opregion_header;
682+struct opregion_acpi;
683+struct opregion_swsci;
684+struct opregion_asle;
685+
686 struct intel_opregion {
687 struct opregion_header *header;
688 struct opregion_acpi *acpi;
689@@ -105,7 +110,7 @@ typedef struct drm_i915_private {
690 drm_dma_handle_t *status_page_dmah;
691 void *hw_status_page;
692 dma_addr_t dma_status_page;
693- unsigned long counter;
694+ uint32_t counter;
695 unsigned int status_gfx_addr;
696 drm_local_map_t hws_map;
697
698@@ -247,16 +252,17 @@ extern int i915_irq_emit(struct drm_device *dev, void *data,
699 extern int i915_irq_wait(struct drm_device *dev, void *data,
700 struct drm_file *file_priv);
701
702-extern int i915_driver_vblank_wait(struct drm_device *dev, unsigned int *sequence);
703-extern int i915_driver_vblank_wait2(struct drm_device *dev, unsigned int *sequence);
704 extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS);
705 extern void i915_driver_irq_preinstall(struct drm_device * dev);
706-extern void i915_driver_irq_postinstall(struct drm_device * dev);
707+extern int i915_driver_irq_postinstall(struct drm_device *dev);
708 extern void i915_driver_irq_uninstall(struct drm_device * dev);
709 extern int i915_vblank_pipe_set(struct drm_device *dev, void *data,
710 struct drm_file *file_priv);
711 extern int i915_vblank_pipe_get(struct drm_device *dev, void *data,
712 struct drm_file *file_priv);
713+extern int i915_enable_vblank(struct drm_device *dev, int crtc);
714+extern void i915_disable_vblank(struct drm_device *dev, int crtc);
715+extern u32 i915_get_vblank_counter(struct drm_device *dev, int crtc);
716 extern int i915_vblank_swap(struct drm_device *dev, void *data,
717 struct drm_file *file_priv);
718 extern void i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask);
719@@ -278,6 +284,10 @@ extern void i915_mem_release(struct drm_device * dev,
720 extern int i915_save_state(struct drm_device *dev);
721 extern int i915_restore_state(struct drm_device *dev);
722
723+/* i915_suspend.c */
724+extern int i915_save_state(struct drm_device *dev);
725+extern int i915_restore_state(struct drm_device *dev);
726+
727 /* i915_opregion.c */
728 extern int intel_opregion_init(struct drm_device *dev);
729 extern void intel_opregion_free(struct drm_device *dev);
730diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
731index ae7d3a8..f875959 100644
732--- a/drivers/gpu/drm/i915/i915_irq.c
733+++ b/drivers/gpu/drm/i915/i915_irq.c
734@@ -35,9 +35,8 @@
735
736 /** These are the interrupts used by the driver */
737 #define I915_INTERRUPT_ENABLE_MASK (I915_USER_INTERRUPT | \
738- I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT | \
739- I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT | \
740 I915_ASLE_INTERRUPT | \
741+ I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | \
742 I915_DISPLAY_PIPE_B_EVENT_INTERRUPT)
743
744 void
745@@ -61,6 +60,64 @@ i915_disable_irq(drm_i915_private_t *dev_priv, u32 mask)
746 }
747
748 /**
749+ * i915_get_pipe - return the the pipe associated with a given plane
750+ * @dev: DRM device
751+ * @plane: plane to look for
752+ *
753+ * The Intel Mesa & 2D drivers call the vblank routines with a plane number
754+ * rather than a pipe number, since they may not always be equal. This routine
755+ * maps the given @plane back to a pipe number.
756+ */
757+static int
758+i915_get_pipe(struct drm_device *dev, int plane)
759+{
760+ drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
761+ u32 dspcntr;
762+
763+ dspcntr = plane ? I915_READ(DSPBCNTR) : I915_READ(DSPACNTR);
764+
765+ return dspcntr & DISPPLANE_SEL_PIPE_MASK ? 1 : 0;
766+}
767+
768+/**
769+ * i915_get_plane - return the the plane associated with a given pipe
770+ * @dev: DRM device
771+ * @pipe: pipe to look for
772+ *
773+ * The Intel Mesa & 2D drivers call the vblank routines with a plane number
774+ * rather than a plane number, since they may not always be equal. This routine
775+ * maps the given @pipe back to a plane number.
776+ */
777+static int
778+i915_get_plane(struct drm_device *dev, int pipe)
779+{
780+ if (i915_get_pipe(dev, 0) == pipe)
781+ return 0;
782+ return 1;
783+}
784+
785+/**
786+ * i915_pipe_enabled - check if a pipe is enabled
787+ * @dev: DRM device
788+ * @pipe: pipe to check
789+ *
790+ * Reading certain registers when the pipe is disabled can hang the chip.
791+ * Use this routine to make sure the PLL is running and the pipe is active
792+ * before reading such registers if unsure.
793+ */
794+static int
795+i915_pipe_enabled(struct drm_device *dev, int pipe)
796+{
797+ drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
798+ unsigned long pipeconf = pipe ? PIPEBCONF : PIPEACONF;
799+
800+ if (I915_READ(pipeconf) & PIPEACONF_ENABLE)
801+ return 1;
802+
803+ return 0;
804+}
805+
806+/**
807 * Emit blits for scheduled buffer swaps.
808 *
809 * This function will be called with the HW lock held.
810@@ -71,8 +128,7 @@ static void i915_vblank_tasklet(struct drm_device *dev)
811 unsigned long irqflags;
812 struct list_head *list, *tmp, hits, *hit;
813 int nhits, nrects, slice[2], upper[2], lower[2], i;
814- unsigned counter[2] = { atomic_read(&dev->vbl_received),
815- atomic_read(&dev->vbl_received2) };
816+ unsigned counter[2];
817 struct drm_drawable_info *drw;
818 drm_i915_sarea_t *sarea_priv = dev_priv->sarea_priv;
819 u32 cpp = dev_priv->cpp;
820@@ -94,6 +150,9 @@ static void i915_vblank_tasklet(struct drm_device *dev)
821 src_pitch >>= 2;
822 }
823
824+ counter[0] = drm_vblank_count(dev, 0);
825+ counter[1] = drm_vblank_count(dev, 1);
826+
827 DRM_DEBUG("\n");
828
829 INIT_LIST_HEAD(&hits);
830@@ -106,12 +165,14 @@ static void i915_vblank_tasklet(struct drm_device *dev)
831 list_for_each_safe(list, tmp, &dev_priv->vbl_swaps.head) {
832 drm_i915_vbl_swap_t *vbl_swap =
833 list_entry(list, drm_i915_vbl_swap_t, head);
834+ int pipe = i915_get_pipe(dev, vbl_swap->plane);
835
836- if ((counter[vbl_swap->pipe] - vbl_swap->sequence) > (1<<23))
837+ if ((counter[pipe] - vbl_swap->sequence) > (1<<23))
838 continue;
839
840 list_del(list);
841 dev_priv->swaps_pending--;
842+ drm_vblank_put(dev, pipe);
843
844 spin_unlock(&dev_priv->swaps_lock);
845 spin_lock(&dev->drw_lock);
846@@ -204,7 +265,7 @@ static void i915_vblank_tasklet(struct drm_device *dev)
847 drm_i915_vbl_swap_t *swap_hit =
848 list_entry(hit, drm_i915_vbl_swap_t, head);
849 struct drm_clip_rect *rect;
850- int num_rects, pipe;
851+ int num_rects, plane;
852 unsigned short top, bottom;
853
854 drw = drm_get_drawable_info(dev, swap_hit->drw_id);
855@@ -213,9 +274,9 @@ static void i915_vblank_tasklet(struct drm_device *dev)
856 continue;
857
858 rect = drw->rects;
859- pipe = swap_hit->pipe;
860- top = upper[pipe];
861- bottom = lower[pipe];
862+ plane = swap_hit->plane;
863+ top = upper[plane];
864+ bottom = lower[plane];
865
866 for (num_rects = drw->num_rects; num_rects--; rect++) {
867 int y1 = max(rect->y1, top);
868@@ -252,22 +313,54 @@ static void i915_vblank_tasklet(struct drm_device *dev)
869 }
870 }
871
872+u32 i915_get_vblank_counter(struct drm_device *dev, int plane)
873+{
874+ drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
875+ unsigned long high_frame;
876+ unsigned long low_frame;
877+ u32 high1, high2, low, count;
878+ int pipe;
879+
880+ pipe = i915_get_pipe(dev, plane);
881+ high_frame = pipe ? PIPEBFRAMEHIGH : PIPEAFRAMEHIGH;
882+ low_frame = pipe ? PIPEBFRAMEPIXEL : PIPEAFRAMEPIXEL;
883+
884+ if (!i915_pipe_enabled(dev, pipe)) {
885+ DRM_ERROR("trying to get vblank count for disabled pipe %d\n", pipe);
886+ return 0;
887+ }
888+
889+ /*
890+ * High & low register fields aren't synchronized, so make sure
891+ * we get a low value that's stable across two reads of the high
892+ * register.
893+ */
894+ do {
895+ high1 = ((I915_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >>
896+ PIPE_FRAME_HIGH_SHIFT);
897+ low = ((I915_READ(low_frame) & PIPE_FRAME_LOW_MASK) >>
898+ PIPE_FRAME_LOW_SHIFT);
899+ high2 = ((I915_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >>
900+ PIPE_FRAME_HIGH_SHIFT);
901+ } while (high1 != high2);
902+
903+ count = (high1 << 8) | low;
904+
905+ return count;
906+}
907+
908 irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
909 {
910 struct drm_device *dev = (struct drm_device *) arg;
911 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
912- u32 pipea_stats, pipeb_stats;
913 u32 iir;
914-
915- pipea_stats = I915_READ(PIPEASTAT);
916- pipeb_stats = I915_READ(PIPEBSTAT);
917+ u32 pipea_stats, pipeb_stats;
918+ int vblank = 0;
919
920 if (dev->pdev->msi_enabled)
921 I915_WRITE(IMR, ~0);
922 iir = I915_READ(IIR);
923
924- DRM_DEBUG("iir=%08x\n", iir);
925-
926 if (iir == 0) {
927 if (dev->pdev->msi_enabled) {
928 I915_WRITE(IMR, dev_priv->irq_mask_reg);
929@@ -276,48 +369,56 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
930 return IRQ_NONE;
931 }
932
933- I915_WRITE(PIPEASTAT, pipea_stats);
934- I915_WRITE(PIPEBSTAT, pipeb_stats);
935-
936- I915_WRITE(IIR, iir);
937- if (dev->pdev->msi_enabled)
938- I915_WRITE(IMR, dev_priv->irq_mask_reg);
939- (void) I915_READ(IIR); /* Flush posted writes */
940-
941- dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
942-
943- if (iir & I915_USER_INTERRUPT)
944- DRM_WAKEUP(&dev_priv->irq_queue);
945-
946- if (iir & (I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT |
947- I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT)) {
948- int vblank_pipe = dev_priv->vblank_pipe;
949-
950- if ((vblank_pipe &
951- (DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B))
952- == (DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B)) {
953- if (iir & I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT)
954- atomic_inc(&dev->vbl_received);
955- if (iir & I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT)
956- atomic_inc(&dev->vbl_received2);
957- } else if (((iir & I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT) &&
958- (vblank_pipe & DRM_I915_VBLANK_PIPE_A)) ||
959- ((iir & I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT) &&
960- (vblank_pipe & DRM_I915_VBLANK_PIPE_B)))
961- atomic_inc(&dev->vbl_received);
962+ /*
963+ * Clear the PIPE(A|B)STAT regs before the IIR otherwise
964+ * we may get extra interrupts.
965+ */
966+ if (iir & I915_DISPLAY_PIPE_A_EVENT_INTERRUPT) {
967+ pipea_stats = I915_READ(PIPEASTAT);
968+ if (!(dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_A))
969+ pipea_stats &= ~(PIPE_START_VBLANK_INTERRUPT_ENABLE |
970+ PIPE_VBLANK_INTERRUPT_ENABLE);
971+ else if (pipea_stats & (PIPE_START_VBLANK_INTERRUPT_STATUS|
972+ PIPE_VBLANK_INTERRUPT_STATUS)) {
973+ vblank++;
974+ drm_handle_vblank(dev, i915_get_plane(dev, 0));
975+ }
976
977- DRM_WAKEUP(&dev->vbl_queue);
978- drm_vbl_send_signals(dev);
979+ I915_WRITE(PIPEASTAT, pipea_stats);
980+ }
981+ if (iir & I915_DISPLAY_PIPE_B_EVENT_INTERRUPT) {
982+ pipeb_stats = I915_READ(PIPEBSTAT);
983+ /* Ack the event */
984+ I915_WRITE(PIPEBSTAT, pipeb_stats);
985+
986+ /* The vblank interrupt gets enabled even if we didn't ask for
987+ it, so make sure it's shut down again */
988+ if (!(dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_B))
989+ pipeb_stats &= ~(PIPE_START_VBLANK_INTERRUPT_ENABLE |
990+ PIPE_VBLANK_INTERRUPT_ENABLE);
991+ else if (pipeb_stats & (PIPE_START_VBLANK_INTERRUPT_STATUS|
992+ PIPE_VBLANK_INTERRUPT_STATUS)) {
993+ vblank++;
994+ drm_handle_vblank(dev, i915_get_plane(dev, 1));
995+ }
996
997- if (dev_priv->swaps_pending > 0)
998- drm_locked_tasklet(dev, i915_vblank_tasklet);
999+ if (pipeb_stats & I915_LEGACY_BLC_EVENT_STATUS)
1000+ opregion_asle_intr(dev);
1001+ I915_WRITE(PIPEBSTAT, pipeb_stats);
1002 }
1003
1004 if (iir & I915_ASLE_INTERRUPT)
1005 opregion_asle_intr(dev);
1006
1007- if (iir & I915_DISPLAY_PIPE_B_EVENT_INTERRUPT)
1008- opregion_asle_intr(dev);
1009+ dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
1010+
1011+ if (dev->pdev->msi_enabled)
1012+ I915_WRITE(IMR, dev_priv->irq_mask_reg);
1013+ I915_WRITE(IIR, iir);
1014+ (void) I915_READ(IIR);
1015+
1016+ if (vblank && dev_priv->swaps_pending > 0)
1017+ drm_locked_tasklet(dev, i915_vblank_tasklet);
1018
1019 return IRQ_HANDLED;
1020 }
1021@@ -358,7 +459,7 @@ static void i915_user_irq_get(struct drm_device *dev)
1022 spin_unlock(&dev_priv->user_irq_lock);
1023 }
1024
1025-static void i915_user_irq_put(struct drm_device *dev)
1026+void i915_user_irq_put(struct drm_device *dev)
1027 {
1028 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
1029
1030@@ -395,41 +496,10 @@ static int i915_wait_irq(struct drm_device * dev, int irq_nr)
1031 }
1032
1033 dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
1034- return ret;
1035-}
1036-
1037-static int i915_driver_vblank_do_wait(struct drm_device *dev, unsigned int *sequence,
1038- atomic_t *counter)
1039-{
1040- drm_i915_private_t *dev_priv = dev->dev_private;
1041- unsigned int cur_vblank;
1042- int ret = 0;
1043-
1044- if (!dev_priv) {
1045- DRM_ERROR("called with no initialization\n");
1046- return -EINVAL;
1047- }
1048-
1049- DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
1050- (((cur_vblank = atomic_read(counter))
1051- - *sequence) <= (1<<23)));
1052-
1053- *sequence = cur_vblank;
1054
1055 return ret;
1056 }
1057
1058-
1059-int i915_driver_vblank_wait(struct drm_device *dev, unsigned int *sequence)
1060-{
1061- return i915_driver_vblank_do_wait(dev, sequence, &dev->vbl_received);
1062-}
1063-
1064-int i915_driver_vblank_wait2(struct drm_device *dev, unsigned int *sequence)
1065-{
1066- return i915_driver_vblank_do_wait(dev, sequence, &dev->vbl_received2);
1067-}
1068-
1069 /* Needs the lock as it touches the ring.
1070 */
1071 int i915_irq_emit(struct drm_device *dev, void *data,
1072@@ -472,40 +542,88 @@ int i915_irq_wait(struct drm_device *dev, void *data,
1073 return i915_wait_irq(dev, irqwait->irq_seq);
1074 }
1075
1076+int i915_enable_vblank(struct drm_device *dev, int plane)
1077+{
1078+ drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
1079+ int pipe = i915_get_pipe(dev, plane);
1080+ u32 pipestat_reg = 0;
1081+ u32 pipestat;
1082+
1083+ switch (pipe) {
1084+ case 0:
1085+ pipestat_reg = PIPEASTAT;
1086+ i915_enable_irq(dev_priv, I915_DISPLAY_PIPE_A_EVENT_INTERRUPT);
1087+ break;
1088+ case 1:
1089+ pipestat_reg = PIPEBSTAT;
1090+ i915_enable_irq(dev_priv, I915_DISPLAY_PIPE_B_EVENT_INTERRUPT);
1091+ break;
1092+ default:
1093+ DRM_ERROR("tried to enable vblank on non-existent pipe %d\n",
1094+ pipe);
1095+ break;
1096+ }
1097+
1098+ if (pipestat_reg) {
1099+ pipestat = I915_READ(pipestat_reg);
1100+ if (IS_I965G(dev))
1101+ pipestat |= PIPE_START_VBLANK_INTERRUPT_ENABLE;
1102+ else
1103+ pipestat |= PIPE_VBLANK_INTERRUPT_ENABLE;
1104+ /* Clear any stale interrupt status */
1105+ pipestat |= (PIPE_START_VBLANK_INTERRUPT_STATUS |
1106+ PIPE_VBLANK_INTERRUPT_STATUS);
1107+ I915_WRITE(pipestat_reg, pipestat);
1108+ }
1109+
1110+ return 0;
1111+}
1112+
1113+void i915_disable_vblank(struct drm_device *dev, int plane)
1114+{
1115+ drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
1116+ int pipe = i915_get_pipe(dev, plane);
1117+ u32 pipestat_reg = 0;
1118+ u32 pipestat;
1119+
1120+ switch (pipe) {
1121+ case 0:
1122+ pipestat_reg = PIPEASTAT;
1123+ i915_disable_irq(dev_priv, I915_DISPLAY_PIPE_A_EVENT_INTERRUPT);
1124+ break;
1125+ case 1:
1126+ pipestat_reg = PIPEBSTAT;
1127+ i915_disable_irq(dev_priv, I915_DISPLAY_PIPE_B_EVENT_INTERRUPT);
1128+ break;
1129+ default:
1130+ DRM_ERROR("tried to disable vblank on non-existent pipe %d\n",
1131+ pipe);
1132+ break;
1133+ }
1134+
1135+ if (pipestat_reg) {
1136+ pipestat = I915_READ(pipestat_reg);
1137+ pipestat &= ~(PIPE_START_VBLANK_INTERRUPT_ENABLE |
1138+ PIPE_VBLANK_INTERRUPT_ENABLE);
1139+ /* Clear any stale interrupt status */
1140+ pipestat |= (PIPE_START_VBLANK_INTERRUPT_STATUS |
1141+ PIPE_VBLANK_INTERRUPT_STATUS);
1142+ I915_WRITE(pipestat_reg, pipestat);
1143+ }
1144+}
1145+
1146 /* Set the vblank monitor pipe
1147 */
1148 int i915_vblank_pipe_set(struct drm_device *dev, void *data,
1149 struct drm_file *file_priv)
1150 {
1151 drm_i915_private_t *dev_priv = dev->dev_private;
1152- drm_i915_vblank_pipe_t *pipe = data;
1153- u32 enable_mask = 0, disable_mask = 0;
1154
1155 if (!dev_priv) {
1156 DRM_ERROR("called with no initialization\n");
1157 return -EINVAL;
1158 }
1159
1160- if (pipe->pipe & ~(DRM_I915_VBLANK_PIPE_A|DRM_I915_VBLANK_PIPE_B)) {
1161- DRM_ERROR("called with invalid pipe 0x%x\n", pipe->pipe);
1162- return -EINVAL;
1163- }
1164-
1165- if (pipe->pipe & DRM_I915_VBLANK_PIPE_A)
1166- enable_mask |= I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT;
1167- else
1168- disable_mask |= I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT;
1169-
1170- if (pipe->pipe & DRM_I915_VBLANK_PIPE_B)
1171- enable_mask |= I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
1172- else
1173- disable_mask |= I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
1174-
1175- i915_enable_irq(dev_priv, enable_mask);
1176- i915_disable_irq(dev_priv, disable_mask);
1177-
1178- dev_priv->vblank_pipe = pipe->pipe;
1179-
1180 return 0;
1181 }
1182
1183@@ -514,19 +632,13 @@ int i915_vblank_pipe_get(struct drm_device *dev, void *data,
1184 {
1185 drm_i915_private_t *dev_priv = dev->dev_private;
1186 drm_i915_vblank_pipe_t *pipe = data;
1187- u16 flag;
1188
1189 if (!dev_priv) {
1190 DRM_ERROR("called with no initialization\n");
1191 return -EINVAL;
1192 }
1193
1194- flag = I915_READ(IMR);
1195- pipe->pipe = 0;
1196- if (flag & I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT)
1197- pipe->pipe |= DRM_I915_VBLANK_PIPE_A;
1198- if (flag & I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT)
1199- pipe->pipe |= DRM_I915_VBLANK_PIPE_B;
1200+ pipe->pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B;
1201
1202 return 0;
1203 }
1204@@ -540,9 +652,10 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
1205 drm_i915_private_t *dev_priv = dev->dev_private;
1206 drm_i915_vblank_swap_t *swap = data;
1207 drm_i915_vbl_swap_t *vbl_swap;
1208- unsigned int pipe, seqtype, curseq;
1209+ unsigned int pipe, seqtype, curseq, plane;
1210 unsigned long irqflags;
1211 struct list_head *list;
1212+ int ret;
1213
1214 if (!dev_priv) {
1215 DRM_ERROR("%s called with no initialization\n", __func__);
1216@@ -560,7 +673,8 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
1217 return -EINVAL;
1218 }
1219
1220- pipe = (swap->seqtype & _DRM_VBLANK_SECONDARY) ? 1 : 0;
1221+ plane = (swap->seqtype & _DRM_VBLANK_SECONDARY) ? 1 : 0;
1222+ pipe = i915_get_pipe(dev, plane);
1223
1224 seqtype = swap->seqtype & (_DRM_VBLANK_RELATIVE | _DRM_VBLANK_ABSOLUTE);
1225
1226@@ -579,7 +693,14 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
1227
1228 spin_unlock_irqrestore(&dev->drw_lock, irqflags);
1229
1230- curseq = atomic_read(pipe ? &dev->vbl_received2 : &dev->vbl_received);
1231+ /*
1232+ * We take the ref here and put it when the swap actually completes
1233+ * in the tasklet.
1234+ */
1235+ ret = drm_vblank_get(dev, pipe);
1236+ if (ret)
1237+ return ret;
1238+ curseq = drm_vblank_count(dev, pipe);
1239
1240 if (seqtype == _DRM_VBLANK_RELATIVE)
1241 swap->sequence += curseq;
1242@@ -589,6 +710,7 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
1243 swap->sequence = curseq + 1;
1244 } else {
1245 DRM_DEBUG("Missed target sequence\n");
1246+ drm_vblank_put(dev, pipe);
1247 return -EINVAL;
1248 }
1249 }
1250@@ -599,7 +721,7 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
1251 vbl_swap = list_entry(list, drm_i915_vbl_swap_t, head);
1252
1253 if (vbl_swap->drw_id == swap->drawable &&
1254- vbl_swap->pipe == pipe &&
1255+ vbl_swap->plane == plane &&
1256 vbl_swap->sequence == swap->sequence) {
1257 spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags);
1258 DRM_DEBUG("Already scheduled\n");
1259@@ -611,6 +733,7 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
1260
1261 if (dev_priv->swaps_pending >= 100) {
1262 DRM_DEBUG("Too many swaps queued\n");
1263+ drm_vblank_put(dev, pipe);
1264 return -EBUSY;
1265 }
1266
1267@@ -618,13 +741,14 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
1268
1269 if (!vbl_swap) {
1270 DRM_ERROR("Failed to allocate memory to queue swap\n");
1271+ drm_vblank_put(dev, pipe);
1272 return -ENOMEM;
1273 }
1274
1275 DRM_DEBUG("\n");
1276
1277 vbl_swap->drw_id = swap->drawable;
1278- vbl_swap->pipe = pipe;
1279+ vbl_swap->plane = plane;
1280 vbl_swap->sequence = swap->sequence;
1281
1282 spin_lock_irqsave(&dev_priv->swaps_lock, irqflags);
1283@@ -643,28 +767,32 @@ void i915_driver_irq_preinstall(struct drm_device * dev)
1284 {
1285 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
1286
1287- I915_WRITE(HWSTAM, 0xfffe);
1288- I915_WRITE(IMR, 0x0);
1289+ I915_WRITE(HWSTAM, 0xeffe);
1290+ I915_WRITE(IMR, 0xffffffff);
1291 I915_WRITE(IER, 0x0);
1292 }
1293
1294-void i915_driver_irq_postinstall(struct drm_device * dev)
1295+int i915_driver_irq_postinstall(struct drm_device *dev)
1296 {
1297 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
1298+ int ret, num_pipes = 2;
1299
1300 spin_lock_init(&dev_priv->swaps_lock);
1301 INIT_LIST_HEAD(&dev_priv->vbl_swaps.head);
1302 dev_priv->swaps_pending = 0;
1303
1304- if (!dev_priv->vblank_pipe)
1305- dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A;
1306-
1307 /* Set initial unmasked IRQs to just the selected vblank pipes. */
1308 dev_priv->irq_mask_reg = ~0;
1309- if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_A)
1310- dev_priv->irq_mask_reg &= ~I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT;
1311- if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_B)
1312- dev_priv->irq_mask_reg &= ~I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
1313+
1314+ ret = drm_vblank_init(dev, num_pipes);
1315+ if (ret)
1316+ return ret;
1317+
1318+ dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B;
1319+ dev_priv->irq_mask_reg &= ~I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT;
1320+ dev_priv->irq_mask_reg &= ~I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
1321+
1322+ dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */
1323
1324 dev_priv->irq_mask_reg &= I915_INTERRUPT_ENABLE_MASK;
1325
1326@@ -673,22 +801,29 @@ void i915_driver_irq_postinstall(struct drm_device * dev)
1327 (void) I915_READ(IER);
1328
1329 opregion_enable_asle(dev);
1330-
1331 DRM_INIT_WAITQUEUE(&dev_priv->irq_queue);
1332+
1333+ return 0;
1334 }
1335
1336 void i915_driver_irq_uninstall(struct drm_device * dev)
1337 {
1338 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
1339- u16 temp;
1340+ u32 temp;
1341
1342 if (!dev_priv)
1343 return;
1344
1345- I915_WRITE(HWSTAM, 0xffff);
1346- I915_WRITE(IMR, 0xffff);
1347+ dev_priv->vblank_pipe = 0;
1348+
1349+ I915_WRITE(HWSTAM, 0xffffffff);
1350+ I915_WRITE(IMR, 0xffffffff);
1351 I915_WRITE(IER, 0x0);
1352
1353+ temp = I915_READ(PIPEASTAT);
1354+ I915_WRITE(PIPEASTAT, temp);
1355+ temp = I915_READ(PIPEBSTAT);
1356+ I915_WRITE(PIPEBSTAT, temp);
1357 temp = I915_READ(IIR);
1358 I915_WRITE(IIR, temp);
1359 }
1360diff --git a/include/drm/drm.h b/include/drm/drm.h
1361index 0864c69..15e5503 100644
1362--- a/include/drm/drm.h
1363+++ b/include/drm/drm.h
1364@@ -454,6 +454,7 @@ struct drm_irq_busid {
1365 enum drm_vblank_seq_type {
1366 _DRM_VBLANK_ABSOLUTE = 0x0, /**< Wait for specific vblank sequence number */
1367 _DRM_VBLANK_RELATIVE = 0x1, /**< Wait for given number of vblanks */
1368+ _DRM_VBLANK_FLIP = 0x8000000, /**< Scheduled buffer swap should flip */
1369 _DRM_VBLANK_NEXTONMISS = 0x10000000, /**< If missed, wait for next vblank */
1370 _DRM_VBLANK_SECONDARY = 0x20000000, /**< Secondary display controller */
1371 _DRM_VBLANK_SIGNAL = 0x40000000 /**< Send signal instead of blocking */
1372@@ -486,6 +487,19 @@ union drm_wait_vblank {
1373 struct drm_wait_vblank_reply reply;
1374 };
1375
1376+#define _DRM_PRE_MODESET 1
1377+#define _DRM_POST_MODESET 2
1378+
1379+/**
1380+ * DRM_IOCTL_MODESET_CTL ioctl argument type
1381+ *
1382+ * \sa drmModesetCtl().
1383+ */
1384+struct drm_modeset_ctl {
1385+ uint32_t crtc;
1386+ uint32_t cmd;
1387+};
1388+
1389 /**
1390 * DRM_IOCTL_AGP_ENABLE ioctl argument type.
1391 *
1392@@ -570,6 +584,7 @@ struct drm_set_version {
1393 #define DRM_IOCTL_GET_CLIENT DRM_IOWR(0x05, struct drm_client)
1394 #define DRM_IOCTL_GET_STATS DRM_IOR( 0x06, struct drm_stats)
1395 #define DRM_IOCTL_SET_VERSION DRM_IOWR(0x07, struct drm_set_version)
1396+#define DRM_IOCTL_MODESET_CTL DRM_IOW(0x08, struct drm_modeset_ctl)
1397
1398 #define DRM_IOCTL_SET_UNIQUE DRM_IOW( 0x10, struct drm_unique)
1399 #define DRM_IOCTL_AUTH_MAGIC DRM_IOW( 0x11, struct drm_auth)
1400diff --git a/include/drm/drmP.h b/include/drm/drmP.h
1401index 1c1b13e..e79ce07 100644
1402--- a/include/drm/drmP.h
1403+++ b/include/drm/drmP.h
1404@@ -580,11 +580,54 @@ struct drm_driver {
1405 int (*kernel_context_switch) (struct drm_device *dev, int old,
1406 int new);
1407 void (*kernel_context_switch_unlock) (struct drm_device *dev);
1408- int (*vblank_wait) (struct drm_device *dev, unsigned int *sequence);
1409- int (*vblank_wait2) (struct drm_device *dev, unsigned int *sequence);
1410 int (*dri_library_name) (struct drm_device *dev, char *buf);
1411
1412 /**
1413+ * get_vblank_counter - get raw hardware vblank counter
1414+ * @dev: DRM device
1415+ * @crtc: counter to fetch
1416+ *
1417+ * Driver callback for fetching a raw hardware vblank counter
1418+ * for @crtc. If a device doesn't have a hardware counter, the
1419+ * driver can simply return the value of drm_vblank_count and
1420+ * make the enable_vblank() and disable_vblank() hooks into no-ops,
1421+ * leaving interrupts enabled at all times.
1422+ *
1423+ * Wraparound handling and loss of events due to modesetting is dealt
1424+ * with in the DRM core code.
1425+ *
1426+ * RETURNS
1427+ * Raw vblank counter value.
1428+ */
1429+ u32 (*get_vblank_counter) (struct drm_device *dev, int crtc);
1430+
1431+ /**
1432+ * enable_vblank - enable vblank interrupt events
1433+ * @dev: DRM device
1434+ * @crtc: which irq to enable
1435+ *
1436+ * Enable vblank interrupts for @crtc. If the device doesn't have
1437+ * a hardware vblank counter, this routine should be a no-op, since
1438+ * interrupts will have to stay on to keep the count accurate.
1439+ *
1440+ * RETURNS
1441+ * Zero on success, appropriate errno if the given @crtc's vblank
1442+ * interrupt cannot be enabled.
1443+ */
1444+ int (*enable_vblank) (struct drm_device *dev, int crtc);
1445+
1446+ /**
1447+ * disable_vblank - disable vblank interrupt events
1448+ * @dev: DRM device
1449+ * @crtc: which irq to enable
1450+ *
1451+ * Disable vblank interrupts for @crtc. If the device doesn't have
1452+ * a hardware vblank counter, this routine should be a no-op, since
1453+ * interrupts will have to stay on to keep the count accurate.
1454+ */
1455+ void (*disable_vblank) (struct drm_device *dev, int crtc);
1456+
1457+ /**
1458 * Called by \c drm_device_is_agp. Typically used to determine if a
1459 * card is really attached to AGP or not.
1460 *
1461@@ -601,7 +644,7 @@ struct drm_driver {
1462
1463 irqreturn_t(*irq_handler) (DRM_IRQ_ARGS);
1464 void (*irq_preinstall) (struct drm_device *dev);
1465- void (*irq_postinstall) (struct drm_device *dev);
1466+ int (*irq_postinstall) (struct drm_device *dev);
1467 void (*irq_uninstall) (struct drm_device *dev);
1468 void (*reclaim_buffers) (struct drm_device *dev,
1469 struct drm_file * file_priv);
1470@@ -730,13 +773,28 @@ struct drm_device {
1471 /** \name VBLANK IRQ support */
1472 /*@{ */
1473
1474- wait_queue_head_t vbl_queue; /**< VBLANK wait queue */
1475- atomic_t vbl_received;
1476- atomic_t vbl_received2; /**< number of secondary VBLANK interrupts */
1477+ /*
1478+ * At load time, disabling the vblank interrupt won't be allowed since
1479+ * old clients may not call the modeset ioctl and therefore misbehave.
1480+ * Once the modeset ioctl *has* been called though, we can safely
1481+ * disable them when unused.
1482+ */
1483+ int vblank_disable_allowed;
1484+
1485+ wait_queue_head_t *vbl_queue; /**< VBLANK wait queue */
1486+ atomic_t *_vblank_count; /**< number of VBLANK interrupts (driver must alloc the right number of counters) */
1487 spinlock_t vbl_lock;
1488- struct list_head vbl_sigs; /**< signal list to send on VBLANK */
1489- struct list_head vbl_sigs2; /**< signals to send on secondary VBLANK */
1490- unsigned int vbl_pending;
1491+ struct list_head *vbl_sigs; /**< signal list to send on VBLANK */
1492+ atomic_t vbl_signal_pending; /* number of signals pending on all crtcs*/
1493+ atomic_t *vblank_refcount; /* number of users of vblank interruptsper crtc */
1494+ u32 *last_vblank; /* protected by dev->vbl_lock, used */
1495+ /* for wraparound handling */
1496+ int *vblank_enabled; /* so we don't call enable more than
1497+ once per disable */
1498+ int *vblank_inmodeset; /* Display driver is setting mode */
1499+ struct timer_list vblank_disable_timer;
1500+
1501+ u32 max_vblank_count; /**< size of vblank counter register */
1502 spinlock_t tasklet_lock; /**< For drm_locked_tasklet */
1503 void (*locked_tasklet_func)(struct drm_device *dev);
1504
1505@@ -757,6 +815,7 @@ struct drm_device {
1506 struct pci_controller *hose;
1507 #endif
1508 struct drm_sg_mem *sg; /**< Scatter gather memory */
1509+ int num_crtcs; /**< Number of CRTCs on this device */
1510 void *dev_private; /**< device private data */
1511 struct drm_sigdata sigdata; /**< For block_all_signals */
1512 sigset_t sigmask;
1513@@ -990,10 +1049,19 @@ extern void drm_driver_irq_preinstall(struct drm_device *dev);
1514 extern void drm_driver_irq_postinstall(struct drm_device *dev);
1515 extern void drm_driver_irq_uninstall(struct drm_device *dev);
1516
1517+extern int drm_vblank_init(struct drm_device *dev, int num_crtcs);
1518 extern int drm_wait_vblank(struct drm_device *dev, void *data,
1519- struct drm_file *file_priv);
1520+ struct drm_file *filp);
1521 extern int drm_vblank_wait(struct drm_device *dev, unsigned int *vbl_seq);
1522-extern void drm_vbl_send_signals(struct drm_device *dev);
1523+extern void drm_locked_tasklet(struct drm_device *dev,
1524+ void(*func)(struct drm_device *));
1525+extern u32 drm_vblank_count(struct drm_device *dev, int crtc);
1526+extern void drm_handle_vblank(struct drm_device *dev, int crtc);
1527+extern int drm_vblank_get(struct drm_device *dev, int crtc);
1528+extern void drm_vblank_put(struct drm_device *dev, int crtc);
1529+/* Modesetting support */
1530+extern int drm_modeset_ctl(struct drm_device *dev, void *data,
1531+ struct drm_file *file_priv);
1532 extern void drm_locked_tasklet(struct drm_device *dev, void(*func)(struct drm_device*));
1533
1534 /* AGP/GART support (drm_agpsupport.h) */
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0012-Export-shmem_file_setup-for-DRM-GEM.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0012-Export-shmem_file_setup-for-DRM-GEM.patch
new file mode 100644
index 0000000000..642d89ba76
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0012-Export-shmem_file_setup-for-DRM-GEM.patch
@@ -0,0 +1,25 @@
1commit 48e13db26a25ebaf61f1fc28f612d6b35ddf1965
2Author: Keith Packard <keithp@keithp.com>
3Date: Fri Jun 20 00:08:06 2008 -0700
4
5 Export shmem_file_setup for DRM-GEM
6
7 GEM needs to create shmem files to back buffer objects. Though currently
8 creation of files for objects could have been driven from userland, the
9 modesetting work will require allocation of buffer objects before userland
10 is running, for boot-time message display.
11
12 Signed-off-by: Eric Anholt <eric@anholt.net>
13
14diff --git a/mm/shmem.c b/mm/shmem.c
15index 04fb4f1..515909d 100644
16--- a/mm/shmem.c
17+++ b/mm/shmem.c
18@@ -2582,6 +2582,7 @@ put_memory:
19 shmem_unacct_size(flags, size);
20 return ERR_PTR(error);
21 }
22+EXPORT_SYMBOL(shmem_file_setup);
23
24 /**
25 * shmem_zero_setup - setup a shared anonymous mapping
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0013-Export-kmap_atomic_pfn-for-DRM-GEM.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0013-Export-kmap_atomic_pfn-for-DRM-GEM.patch
new file mode 100644
index 0000000000..cc90d46262
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0013-Export-kmap_atomic_pfn-for-DRM-GEM.patch
@@ -0,0 +1,24 @@
1commit 25eaa97fc74b225e13cf11ed8d770192ddc9355d
2Author: Eric Anholt <eric@anholt.net>
3Date: Thu Aug 21 12:53:33 2008 -0700
4
5 Export kmap_atomic_pfn for DRM-GEM.
6
7 The driver would like to map IO space directly for copying data in when
8 appropriate, to avoid CPU cache flushing for streaming writes.
9 kmap_atomic_pfn lets us avoid IPIs associated with ioremap for this process.
10
11 Signed-off-by: Eric Anholt <eric@anholt.net>
12
13diff --git a/arch/x86/mm/highmem_32.c b/arch/x86/mm/highmem_32.c
14index 165c871..d52e91d 100644
15--- a/arch/x86/mm/highmem_32.c
16+++ b/arch/x86/mm/highmem_32.c
17@@ -137,6 +137,7 @@ void *kmap_atomic_pfn(unsigned long pfn, enum km_type type)
18
19 return (void*) vaddr;
20 }
21+EXPORT_SYMBOL(kmap_atomic_pfn);
22
23 struct page *kmap_atomic_to_page(void *ptr)
24 {
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0014-drm-Add-GEM-graphics-execution-manager-to-i915.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0014-drm-Add-GEM-graphics-execution-manager-to-i915.patch
new file mode 100644
index 0000000000..95cca5d0c6
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0014-drm-Add-GEM-graphics-execution-manager-to-i915.patch
@@ -0,0 +1,5483 @@
1commit c97398223c6a505fac2c783a624dc80e0aa5d5d0
2Author: Eric Anholt <eric@anholt.net>
3Date: Wed Jul 30 12:06:12 2008 -0700
4
5 drm: Add GEM ("graphics execution manager") to i915 driver.
6
7 GEM allows the creation of persistent buffer objects accessible by the
8 graphics device through new ioctls for managing execution of commands on the
9 device. The userland API is almost entirely driver-specific to ensure that
10 any driver building on this model can easily map the interface to individual
11 driver requirements.
12
13 GEM is used by the 2d driver for managing its internal state allocations and
14 will be used for pixmap storage to reduce memory consumption and enable
15 zero-copy GLX_EXT_texture_from_pixmap, and in the 3d driver is used to enable
16 GL_EXT_framebuffer_object and GL_ARB_pixel_buffer_object.
17
18 Signed-off-by: Eric Anholt <eric@anholt.net>
19
20diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
21index e9f9a97..74da994 100644
22--- a/drivers/gpu/drm/Makefile
23+++ b/drivers/gpu/drm/Makefile
24@@ -4,8 +4,9 @@
25
26 ccflags-y := -Iinclude/drm
27
28-drm-y := drm_auth.o drm_bufs.o drm_context.o drm_dma.o drm_drawable.o \
29- drm_drv.o drm_fops.o drm_ioctl.o drm_irq.o \
30+drm-y := drm_auth.o drm_bufs.o drm_cache.o \
31+ drm_context.o drm_dma.o drm_drawable.o \
32+ drm_drv.o drm_fops.o drm_gem.o drm_ioctl.o drm_irq.o \
33 drm_lock.o drm_memory.o drm_proc.o drm_stub.o drm_vm.o \
34 drm_agpsupport.o drm_scatter.o ati_pcigart.o drm_pci.o \
35 drm_sysfs.o drm_hashtab.o drm_sman.o drm_mm.o
36diff --git a/drivers/gpu/drm/drm_agpsupport.c b/drivers/gpu/drm/drm_agpsupport.c
37index aefa5ac..2639be2 100644
38--- a/drivers/gpu/drm/drm_agpsupport.c
39+++ b/drivers/gpu/drm/drm_agpsupport.c
40@@ -33,6 +33,7 @@
41
42 #include "drmP.h"
43 #include <linux/module.h>
44+#include <asm/agp.h>
45
46 #if __OS_HAS_AGP
47
48@@ -452,4 +453,52 @@ int drm_agp_unbind_memory(DRM_AGP_MEM * handle)
49 return agp_unbind_memory(handle);
50 }
51
52-#endif /* __OS_HAS_AGP */
53+/**
54+ * Binds a collection of pages into AGP memory at the given offset, returning
55+ * the AGP memory structure containing them.
56+ *
57+ * No reference is held on the pages during this time -- it is up to the
58+ * caller to handle that.
59+ */
60+DRM_AGP_MEM *
61+drm_agp_bind_pages(struct drm_device *dev,
62+ struct page **pages,
63+ unsigned long num_pages,
64+ uint32_t gtt_offset)
65+{
66+ DRM_AGP_MEM *mem;
67+ int ret, i;
68+
69+ DRM_DEBUG("\n");
70+
71+ mem = drm_agp_allocate_memory(dev->agp->bridge, num_pages,
72+ AGP_USER_MEMORY);
73+ if (mem == NULL) {
74+ DRM_ERROR("Failed to allocate memory for %ld pages\n",
75+ num_pages);
76+ return NULL;
77+ }
78+
79+ for (i = 0; i < num_pages; i++)
80+ mem->memory[i] = phys_to_gart(page_to_phys(pages[i]));
81+ mem->page_count = num_pages;
82+
83+ mem->is_flushed = true;
84+ ret = drm_agp_bind_memory(mem, gtt_offset / PAGE_SIZE);
85+ if (ret != 0) {
86+ DRM_ERROR("Failed to bind AGP memory: %d\n", ret);
87+ agp_free_memory(mem);
88+ return NULL;
89+ }
90+
91+ return mem;
92+}
93+EXPORT_SYMBOL(drm_agp_bind_pages);
94+
95+void drm_agp_chipset_flush(struct drm_device *dev)
96+{
97+ agp_flush_chipset(dev->agp->bridge);
98+}
99+EXPORT_SYMBOL(drm_agp_chipset_flush);
100+
101+#endif /* __OS_HAS_AGP */
102diff --git a/drivers/gpu/drm/drm_cache.c b/drivers/gpu/drm/drm_cache.c
103new file mode 100644
104index 0000000..9475f7d
105--- /dev/null
106+++ b/drivers/gpu/drm/drm_cache.c
107@@ -0,0 +1,76 @@
108+/**************************************************************************
109+ *
110+ * Copyright (c) 2006-2007 Tungsten Graphics, Inc., Cedar Park, TX., USA
111+ * All Rights Reserved.
112+ *
113+ * Permission is hereby granted, free of charge, to any person obtaining a
114+ * copy of this software and associated documentation files (the
115+ * "Software"), to deal in the Software without restriction, including
116+ * without limitation the rights to use, copy, modify, merge, publish,
117+ * distribute, sub license, and/or sell copies of the Software, and to
118+ * permit persons to whom the Software is furnished to do so, subject to
119+ * the following conditions:
120+ *
121+ * The above copyright notice and this permission notice (including the
122+ * next paragraph) shall be included in all copies or substantial portions
123+ * of the Software.
124+ *
125+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
126+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
127+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
128+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
129+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
130+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
131+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
132+ *
133+ **************************************************************************/
134+/*
135+ * Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com>
136+ */
137+
138+#include "drmP.h"
139+
140+#if defined(CONFIG_X86)
141+static void
142+drm_clflush_page(struct page *page)
143+{
144+ uint8_t *page_virtual;
145+ unsigned int i;
146+
147+ if (unlikely(page == NULL))
148+ return;
149+
150+ page_virtual = kmap_atomic(page, KM_USER0);
151+ for (i = 0; i < PAGE_SIZE; i += boot_cpu_data.x86_clflush_size)
152+ clflush(page_virtual + i);
153+ kunmap_atomic(page_virtual, KM_USER0);
154+}
155+#endif
156+
157+static void
158+drm_clflush_ipi_handler(void *null)
159+{
160+ wbinvd();
161+}
162+
163+void
164+drm_clflush_pages(struct page *pages[], unsigned long num_pages)
165+{
166+
167+#if defined(CONFIG_X86)
168+ if (cpu_has_clflush) {
169+ unsigned long i;
170+
171+ mb();
172+ for (i = 0; i < num_pages; ++i)
173+ drm_clflush_page(*pages++);
174+ mb();
175+
176+ return;
177+ }
178+#endif
179+
180+ if (on_each_cpu(drm_clflush_ipi_handler, NULL, 1) != 0)
181+ DRM_ERROR("Timed out waiting for cache flush.\n");
182+}
183+EXPORT_SYMBOL(drm_clflush_pages);
184diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
185index fb45fe7..96f416a 100644
186--- a/drivers/gpu/drm/drm_drv.c
187+++ b/drivers/gpu/drm/drm_drv.c
188@@ -119,6 +119,10 @@ static struct drm_ioctl_desc drm_ioctls[] = {
189 DRM_IOCTL_DEF(DRM_IOCTL_MODESET_CTL, drm_modeset_ctl, 0),
190
191 DRM_IOCTL_DEF(DRM_IOCTL_UPDATE_DRAW, drm_update_drawable_info, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
192+
193+ DRM_IOCTL_DEF(DRM_IOCTL_GEM_CLOSE, drm_gem_close_ioctl, 0),
194+ DRM_IOCTL_DEF(DRM_IOCTL_GEM_FLINK, drm_gem_flink_ioctl, DRM_AUTH),
195+ DRM_IOCTL_DEF(DRM_IOCTL_GEM_OPEN, drm_gem_open_ioctl, DRM_AUTH),
196 };
197
198 #define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls )
199diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
200index dcf8b4d..0d46627 100644
201--- a/drivers/gpu/drm/drm_fops.c
202+++ b/drivers/gpu/drm/drm_fops.c
203@@ -256,6 +256,9 @@ static int drm_open_helper(struct inode *inode, struct file *filp,
204
205 INIT_LIST_HEAD(&priv->lhead);
206
207+ if (dev->driver->driver_features & DRIVER_GEM)
208+ drm_gem_open(dev, priv);
209+
210 if (dev->driver->open) {
211 ret = dev->driver->open(dev, priv);
212 if (ret < 0)
213@@ -400,6 +403,9 @@ int drm_release(struct inode *inode, struct file *filp)
214 dev->driver->reclaim_buffers(dev, file_priv);
215 }
216
217+ if (dev->driver->driver_features & DRIVER_GEM)
218+ drm_gem_release(dev, file_priv);
219+
220 drm_fasync(-1, filp, 0);
221
222 mutex_lock(&dev->ctxlist_mutex);
223diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
224new file mode 100644
225index 0000000..434155b
226--- /dev/null
227+++ b/drivers/gpu/drm/drm_gem.c
228@@ -0,0 +1,420 @@
229+/*
230+ * Copyright © 2008 Intel Corporation
231+ *
232+ * Permission is hereby granted, free of charge, to any person obtaining a
233+ * copy of this software and associated documentation files (the "Software"),
234+ * to deal in the Software without restriction, including without limitation
235+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
236+ * and/or sell copies of the Software, and to permit persons to whom the
237+ * Software is furnished to do so, subject to the following conditions:
238+ *
239+ * The above copyright notice and this permission notice (including the next
240+ * paragraph) shall be included in all copies or substantial portions of the
241+ * Software.
242+ *
243+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
244+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
245+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
246+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
247+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
248+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
249+ * IN THE SOFTWARE.
250+ *
251+ * Authors:
252+ * Eric Anholt <eric@anholt.net>
253+ *
254+ */
255+
256+#include <linux/types.h>
257+#include <linux/slab.h>
258+#include <linux/mm.h>
259+#include <linux/uaccess.h>
260+#include <linux/fs.h>
261+#include <linux/file.h>
262+#include <linux/module.h>
263+#include <linux/mman.h>
264+#include <linux/pagemap.h>
265+#include "drmP.h"
266+
267+/** @file drm_gem.c
268+ *
269+ * This file provides some of the base ioctls and library routines for
270+ * the graphics memory manager implemented by each device driver.
271+ *
272+ * Because various devices have different requirements in terms of
273+ * synchronization and migration strategies, implementing that is left up to
274+ * the driver, and all that the general API provides should be generic --
275+ * allocating objects, reading/writing data with the cpu, freeing objects.
276+ * Even there, platform-dependent optimizations for reading/writing data with
277+ * the CPU mean we'll likely hook those out to driver-specific calls. However,
278+ * the DRI2 implementation wants to have at least allocate/mmap be generic.
279+ *
280+ * The goal was to have swap-backed object allocation managed through
281+ * struct file. However, file descriptors as handles to a struct file have
282+ * two major failings:
283+ * - Process limits prevent more than 1024 or so being used at a time by
284+ * default.
285+ * - Inability to allocate high fds will aggravate the X Server's select()
286+ * handling, and likely that of many GL client applications as well.
287+ *
288+ * This led to a plan of using our own integer IDs (called handles, following
289+ * DRM terminology) to mimic fds, and implement the fd syscalls we need as
290+ * ioctls. The objects themselves will still include the struct file so
291+ * that we can transition to fds if the required kernel infrastructure shows
292+ * up at a later date, and as our interface with shmfs for memory allocation.
293+ */
294+
295+/**
296+ * Initialize the GEM device fields
297+ */
298+
299+int
300+drm_gem_init(struct drm_device *dev)
301+{
302+ spin_lock_init(&dev->object_name_lock);
303+ idr_init(&dev->object_name_idr);
304+ atomic_set(&dev->object_count, 0);
305+ atomic_set(&dev->object_memory, 0);
306+ atomic_set(&dev->pin_count, 0);
307+ atomic_set(&dev->pin_memory, 0);
308+ atomic_set(&dev->gtt_count, 0);
309+ atomic_set(&dev->gtt_memory, 0);
310+ return 0;
311+}
312+
313+/**
314+ * Allocate a GEM object of the specified size with shmfs backing store
315+ */
316+struct drm_gem_object *
317+drm_gem_object_alloc(struct drm_device *dev, size_t size)
318+{
319+ struct drm_gem_object *obj;
320+
321+ BUG_ON((size & (PAGE_SIZE - 1)) != 0);
322+
323+ obj = kcalloc(1, sizeof(*obj), GFP_KERNEL);
324+
325+ obj->dev = dev;
326+ obj->filp = shmem_file_setup("drm mm object", size, 0);
327+ if (IS_ERR(obj->filp)) {
328+ kfree(obj);
329+ return NULL;
330+ }
331+
332+ kref_init(&obj->refcount);
333+ kref_init(&obj->handlecount);
334+ obj->size = size;
335+ if (dev->driver->gem_init_object != NULL &&
336+ dev->driver->gem_init_object(obj) != 0) {
337+ fput(obj->filp);
338+ kfree(obj);
339+ return NULL;
340+ }
341+ atomic_inc(&dev->object_count);
342+ atomic_add(obj->size, &dev->object_memory);
343+ return obj;
344+}
345+EXPORT_SYMBOL(drm_gem_object_alloc);
346+
347+/**
348+ * Removes the mapping from handle to filp for this object.
349+ */
350+static int
351+drm_gem_handle_delete(struct drm_file *filp, int handle)
352+{
353+ struct drm_device *dev;
354+ struct drm_gem_object *obj;
355+
356+ /* This is gross. The idr system doesn't let us try a delete and
357+ * return an error code. It just spews if you fail at deleting.
358+ * So, we have to grab a lock around finding the object and then
359+ * doing the delete on it and dropping the refcount, or the user
360+ * could race us to double-decrement the refcount and cause a
361+ * use-after-free later. Given the frequency of our handle lookups,
362+ * we may want to use ida for number allocation and a hash table
363+ * for the pointers, anyway.
364+ */
365+ spin_lock(&filp->table_lock);
366+
367+ /* Check if we currently have a reference on the object */
368+ obj = idr_find(&filp->object_idr, handle);
369+ if (obj == NULL) {
370+ spin_unlock(&filp->table_lock);
371+ return -EINVAL;
372+ }
373+ dev = obj->dev;
374+
375+ /* Release reference and decrement refcount. */
376+ idr_remove(&filp->object_idr, handle);
377+ spin_unlock(&filp->table_lock);
378+
379+ mutex_lock(&dev->struct_mutex);
380+ drm_gem_object_handle_unreference(obj);
381+ mutex_unlock(&dev->struct_mutex);
382+
383+ return 0;
384+}
385+
386+/**
387+ * Create a handle for this object. This adds a handle reference
388+ * to the object, which includes a regular reference count. Callers
389+ * will likely want to dereference the object afterwards.
390+ */
391+int
392+drm_gem_handle_create(struct drm_file *file_priv,
393+ struct drm_gem_object *obj,
394+ int *handlep)
395+{
396+ int ret;
397+
398+ /*
399+ * Get the user-visible handle using idr.
400+ */
401+again:
402+ /* ensure there is space available to allocate a handle */
403+ if (idr_pre_get(&file_priv->object_idr, GFP_KERNEL) == 0)
404+ return -ENOMEM;
405+
406+ /* do the allocation under our spinlock */
407+ spin_lock(&file_priv->table_lock);
408+ ret = idr_get_new_above(&file_priv->object_idr, obj, 1, handlep);
409+ spin_unlock(&file_priv->table_lock);
410+ if (ret == -EAGAIN)
411+ goto again;
412+
413+ if (ret != 0)
414+ return ret;
415+
416+ drm_gem_object_handle_reference(obj);
417+ return 0;
418+}
419+EXPORT_SYMBOL(drm_gem_handle_create);
420+
421+/** Returns a reference to the object named by the handle. */
422+struct drm_gem_object *
423+drm_gem_object_lookup(struct drm_device *dev, struct drm_file *filp,
424+ int handle)
425+{
426+ struct drm_gem_object *obj;
427+
428+ spin_lock(&filp->table_lock);
429+
430+ /* Check if we currently have a reference on the object */
431+ obj = idr_find(&filp->object_idr, handle);
432+ if (obj == NULL) {
433+ spin_unlock(&filp->table_lock);
434+ return NULL;
435+ }
436+
437+ drm_gem_object_reference(obj);
438+
439+ spin_unlock(&filp->table_lock);
440+
441+ return obj;
442+}
443+EXPORT_SYMBOL(drm_gem_object_lookup);
444+
445+/**
446+ * Releases the handle to an mm object.
447+ */
448+int
449+drm_gem_close_ioctl(struct drm_device *dev, void *data,
450+ struct drm_file *file_priv)
451+{
452+ struct drm_gem_close *args = data;
453+ int ret;
454+
455+ if (!(dev->driver->driver_features & DRIVER_GEM))
456+ return -ENODEV;
457+
458+ ret = drm_gem_handle_delete(file_priv, args->handle);
459+
460+ return ret;
461+}
462+
463+/**
464+ * Create a global name for an object, returning the name.
465+ *
466+ * Note that the name does not hold a reference; when the object
467+ * is freed, the name goes away.
468+ */
469+int
470+drm_gem_flink_ioctl(struct drm_device *dev, void *data,
471+ struct drm_file *file_priv)
472+{
473+ struct drm_gem_flink *args = data;
474+ struct drm_gem_object *obj;
475+ int ret;
476+
477+ if (!(dev->driver->driver_features & DRIVER_GEM))
478+ return -ENODEV;
479+
480+ obj = drm_gem_object_lookup(dev, file_priv, args->handle);
481+ if (obj == NULL)
482+ return -EINVAL;
483+
484+again:
485+ if (idr_pre_get(&dev->object_name_idr, GFP_KERNEL) == 0)
486+ return -ENOMEM;
487+
488+ spin_lock(&dev->object_name_lock);
489+ if (obj->name) {
490+ spin_unlock(&dev->object_name_lock);
491+ return -EEXIST;
492+ }
493+ ret = idr_get_new_above(&dev->object_name_idr, obj, 1,
494+ &obj->name);
495+ spin_unlock(&dev->object_name_lock);
496+ if (ret == -EAGAIN)
497+ goto again;
498+
499+ if (ret != 0) {
500+ mutex_lock(&dev->struct_mutex);
501+ drm_gem_object_unreference(obj);
502+ mutex_unlock(&dev->struct_mutex);
503+ return ret;
504+ }
505+
506+ /*
507+ * Leave the reference from the lookup around as the
508+ * name table now holds one
509+ */
510+ args->name = (uint64_t) obj->name;
511+
512+ return 0;
513+}
514+
515+/**
516+ * Open an object using the global name, returning a handle and the size.
517+ *
518+ * This handle (of course) holds a reference to the object, so the object
519+ * will not go away until the handle is deleted.
520+ */
521+int
522+drm_gem_open_ioctl(struct drm_device *dev, void *data,
523+ struct drm_file *file_priv)
524+{
525+ struct drm_gem_open *args = data;
526+ struct drm_gem_object *obj;
527+ int ret;
528+ int handle;
529+
530+ if (!(dev->driver->driver_features & DRIVER_GEM))
531+ return -ENODEV;
532+
533+ spin_lock(&dev->object_name_lock);
534+ obj = idr_find(&dev->object_name_idr, (int) args->name);
535+ if (obj)
536+ drm_gem_object_reference(obj);
537+ spin_unlock(&dev->object_name_lock);
538+ if (!obj)
539+ return -ENOENT;
540+
541+ ret = drm_gem_handle_create(file_priv, obj, &handle);
542+ mutex_lock(&dev->struct_mutex);
543+ drm_gem_object_unreference(obj);
544+ mutex_unlock(&dev->struct_mutex);
545+ if (ret)
546+ return ret;
547+
548+ args->handle = handle;
549+ args->size = obj->size;
550+
551+ return 0;
552+}
553+
554+/**
555+ * Called at device open time, sets up the structure for handling refcounting
556+ * of mm objects.
557+ */
558+void
559+drm_gem_open(struct drm_device *dev, struct drm_file *file_private)
560+{
561+ idr_init(&file_private->object_idr);
562+ spin_lock_init(&file_private->table_lock);
563+}
564+
565+/**
566+ * Called at device close to release the file's
567+ * handle references on objects.
568+ */
569+static int
570+drm_gem_object_release_handle(int id, void *ptr, void *data)
571+{
572+ struct drm_gem_object *obj = ptr;
573+
574+ drm_gem_object_handle_unreference(obj);
575+
576+ return 0;
577+}
578+
579+/**
580+ * Called at close time when the filp is going away.
581+ *
582+ * Releases any remaining references on objects by this filp.
583+ */
584+void
585+drm_gem_release(struct drm_device *dev, struct drm_file *file_private)
586+{
587+ mutex_lock(&dev->struct_mutex);
588+ idr_for_each(&file_private->object_idr,
589+ &drm_gem_object_release_handle, NULL);
590+
591+ idr_destroy(&file_private->object_idr);
592+ mutex_unlock(&dev->struct_mutex);
593+}
594+
595+/**
596+ * Called after the last reference to the object has been lost.
597+ *
598+ * Frees the object
599+ */
600+void
601+drm_gem_object_free(struct kref *kref)
602+{
603+ struct drm_gem_object *obj = (struct drm_gem_object *) kref;
604+ struct drm_device *dev = obj->dev;
605+
606+ BUG_ON(!mutex_is_locked(&dev->struct_mutex));
607+
608+ if (dev->driver->gem_free_object != NULL)
609+ dev->driver->gem_free_object(obj);
610+
611+ fput(obj->filp);
612+ atomic_dec(&dev->object_count);
613+ atomic_sub(obj->size, &dev->object_memory);
614+ kfree(obj);
615+}
616+EXPORT_SYMBOL(drm_gem_object_free);
617+
618+/**
619+ * Called after the last handle to the object has been closed
620+ *
621+ * Removes any name for the object. Note that this must be
622+ * called before drm_gem_object_free or we'll be touching
623+ * freed memory
624+ */
625+void
626+drm_gem_object_handle_free(struct kref *kref)
627+{
628+ struct drm_gem_object *obj = container_of(kref,
629+ struct drm_gem_object,
630+ handlecount);
631+ struct drm_device *dev = obj->dev;
632+
633+ /* Remove any name for this object */
634+ spin_lock(&dev->object_name_lock);
635+ if (obj->name) {
636+ idr_remove(&dev->object_name_idr, obj->name);
637+ spin_unlock(&dev->object_name_lock);
638+ /*
639+ * The object name held a reference to this object, drop
640+ * that now.
641+ */
642+ drm_gem_object_unreference(obj);
643+ } else
644+ spin_unlock(&dev->object_name_lock);
645+
646+}
647+EXPORT_SYMBOL(drm_gem_object_handle_free);
648+
649diff --git a/drivers/gpu/drm/drm_memory.c b/drivers/gpu/drm/drm_memory.c
650index 0177012..803bc9e 100644
651--- a/drivers/gpu/drm/drm_memory.c
652+++ b/drivers/gpu/drm/drm_memory.c
653@@ -133,6 +133,7 @@ int drm_free_agp(DRM_AGP_MEM * handle, int pages)
654 {
655 return drm_agp_free_memory(handle) ? 0 : -EINVAL;
656 }
657+EXPORT_SYMBOL(drm_free_agp);
658
659 /** Wrapper around agp_bind_memory() */
660 int drm_bind_agp(DRM_AGP_MEM * handle, unsigned int start)
661@@ -145,6 +146,7 @@ int drm_unbind_agp(DRM_AGP_MEM * handle)
662 {
663 return drm_agp_unbind_memory(handle);
664 }
665+EXPORT_SYMBOL(drm_unbind_agp);
666
667 #else /* __OS_HAS_AGP */
668 static inline void *agp_remap(unsigned long offset, unsigned long size,
669diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
670index dcff9e9..217ad7d 100644
671--- a/drivers/gpu/drm/drm_mm.c
672+++ b/drivers/gpu/drm/drm_mm.c
673@@ -169,6 +169,7 @@ struct drm_mm_node *drm_mm_get_block(struct drm_mm_node * parent,
674
675 return child;
676 }
677+EXPORT_SYMBOL(drm_mm_get_block);
678
679 /*
680 * Put a block. Merge with the previous and / or next block if they are free.
681@@ -217,6 +218,7 @@ void drm_mm_put_block(struct drm_mm_node * cur)
682 drm_free(cur, sizeof(*cur), DRM_MEM_MM);
683 }
684 }
685+EXPORT_SYMBOL(drm_mm_put_block);
686
687 struct drm_mm_node *drm_mm_search_free(const struct drm_mm * mm,
688 unsigned long size,
689@@ -265,6 +267,7 @@ int drm_mm_clean(struct drm_mm * mm)
690
691 return (head->next->next == head);
692 }
693+EXPORT_SYMBOL(drm_mm_search_free);
694
695 int drm_mm_init(struct drm_mm * mm, unsigned long start, unsigned long size)
696 {
697@@ -273,7 +276,7 @@ int drm_mm_init(struct drm_mm * mm, unsigned long start, unsigned long size)
698
699 return drm_mm_create_tail_node(mm, start, size);
700 }
701-
702+EXPORT_SYMBOL(drm_mm_init);
703
704 void drm_mm_takedown(struct drm_mm * mm)
705 {
706diff --git a/drivers/gpu/drm/drm_proc.c b/drivers/gpu/drm/drm_proc.c
707index 93b1e04..d490db4 100644
708--- a/drivers/gpu/drm/drm_proc.c
709+++ b/drivers/gpu/drm/drm_proc.c
710@@ -49,6 +49,10 @@ static int drm_queues_info(char *buf, char **start, off_t offset,
711 int request, int *eof, void *data);
712 static int drm_bufs_info(char *buf, char **start, off_t offset,
713 int request, int *eof, void *data);
714+static int drm_gem_name_info(char *buf, char **start, off_t offset,
715+ int request, int *eof, void *data);
716+static int drm_gem_object_info(char *buf, char **start, off_t offset,
717+ int request, int *eof, void *data);
718 #if DRM_DEBUG_CODE
719 static int drm_vma_info(char *buf, char **start, off_t offset,
720 int request, int *eof, void *data);
721@@ -60,13 +64,16 @@ static int drm_vma_info(char *buf, char **start, off_t offset,
722 static struct drm_proc_list {
723 const char *name; /**< file name */
724 int (*f) (char *, char **, off_t, int, int *, void *); /**< proc callback*/
725+ u32 driver_features; /**< Required driver features for this entry */
726 } drm_proc_list[] = {
727- {"name", drm_name_info},
728- {"mem", drm_mem_info},
729- {"vm", drm_vm_info},
730- {"clients", drm_clients_info},
731- {"queues", drm_queues_info},
732- {"bufs", drm_bufs_info},
733+ {"name", drm_name_info, 0},
734+ {"mem", drm_mem_info, 0},
735+ {"vm", drm_vm_info, 0},
736+ {"clients", drm_clients_info, 0},
737+ {"queues", drm_queues_info, 0},
738+ {"bufs", drm_bufs_info, 0},
739+ {"gem_names", drm_gem_name_info, DRIVER_GEM},
740+ {"gem_objects", drm_gem_object_info, DRIVER_GEM},
741 #if DRM_DEBUG_CODE
742 {"vma", drm_vma_info},
743 #endif
744@@ -90,8 +97,9 @@ static struct drm_proc_list {
745 int drm_proc_init(struct drm_minor *minor, int minor_id,
746 struct proc_dir_entry *root)
747 {
748+ struct drm_device *dev = minor->dev;
749 struct proc_dir_entry *ent;
750- int i, j;
751+ int i, j, ret;
752 char name[64];
753
754 sprintf(name, "%d", minor_id);
755@@ -102,23 +110,42 @@ int drm_proc_init(struct drm_minor *minor, int minor_id,
756 }
757
758 for (i = 0; i < DRM_PROC_ENTRIES; i++) {
759+ u32 features = drm_proc_list[i].driver_features;
760+
761+ if (features != 0 &&
762+ (dev->driver->driver_features & features) != features)
763+ continue;
764+
765 ent = create_proc_entry(drm_proc_list[i].name,
766 S_IFREG | S_IRUGO, minor->dev_root);
767 if (!ent) {
768 DRM_ERROR("Cannot create /proc/dri/%s/%s\n",
769 name, drm_proc_list[i].name);
770- for (j = 0; j < i; j++)
771- remove_proc_entry(drm_proc_list[i].name,
772- minor->dev_root);
773- remove_proc_entry(name, root);
774- minor->dev_root = NULL;
775- return -1;
776+ ret = -1;
777+ goto fail;
778 }
779 ent->read_proc = drm_proc_list[i].f;
780 ent->data = minor;
781 }
782
783+ if (dev->driver->proc_init) {
784+ ret = dev->driver->proc_init(minor);
785+ if (ret) {
786+ DRM_ERROR("DRM: Driver failed to initialize "
787+ "/proc/dri.\n");
788+ goto fail;
789+ }
790+ }
791+
792 return 0;
793+ fail:
794+
795+ for (j = 0; j < i; j++)
796+ remove_proc_entry(drm_proc_list[i].name,
797+ minor->dev_root);
798+ remove_proc_entry(name, root);
799+ minor->dev_root = NULL;
800+ return ret;
801 }
802
803 /**
804@@ -133,12 +160,16 @@ int drm_proc_init(struct drm_minor *minor, int minor_id,
805 */
806 int drm_proc_cleanup(struct drm_minor *minor, struct proc_dir_entry *root)
807 {
808+ struct drm_device *dev = minor->dev;
809 int i;
810 char name[64];
811
812 if (!root || !minor->dev_root)
813 return 0;
814
815+ if (dev->driver->proc_cleanup)
816+ dev->driver->proc_cleanup(minor);
817+
818 for (i = 0; i < DRM_PROC_ENTRIES; i++)
819 remove_proc_entry(drm_proc_list[i].name, minor->dev_root);
820 sprintf(name, "%d", minor->index);
821@@ -480,6 +511,84 @@ static int drm_clients_info(char *buf, char **start, off_t offset,
822 return ret;
823 }
824
825+struct drm_gem_name_info_data {
826+ int len;
827+ char *buf;
828+ int eof;
829+};
830+
831+static int drm_gem_one_name_info(int id, void *ptr, void *data)
832+{
833+ struct drm_gem_object *obj = ptr;
834+ struct drm_gem_name_info_data *nid = data;
835+
836+ DRM_INFO("name %d size %d\n", obj->name, obj->size);
837+ if (nid->eof)
838+ return 0;
839+
840+ nid->len += sprintf(&nid->buf[nid->len],
841+ "%6d%9d%8d%9d\n",
842+ obj->name, obj->size,
843+ atomic_read(&obj->handlecount.refcount),
844+ atomic_read(&obj->refcount.refcount));
845+ if (nid->len > DRM_PROC_LIMIT) {
846+ nid->eof = 1;
847+ return 0;
848+ }
849+ return 0;
850+}
851+
852+static int drm_gem_name_info(char *buf, char **start, off_t offset,
853+ int request, int *eof, void *data)
854+{
855+ struct drm_minor *minor = (struct drm_minor *) data;
856+ struct drm_device *dev = minor->dev;
857+ struct drm_gem_name_info_data nid;
858+
859+ if (offset > DRM_PROC_LIMIT) {
860+ *eof = 1;
861+ return 0;
862+ }
863+
864+ nid.len = sprintf(buf, " name size handles refcount\n");
865+ nid.buf = buf;
866+ nid.eof = 0;
867+ idr_for_each(&dev->object_name_idr, drm_gem_one_name_info, &nid);
868+
869+ *start = &buf[offset];
870+ *eof = 0;
871+ if (nid.len > request + offset)
872+ return request;
873+ *eof = 1;
874+ return nid.len - offset;
875+}
876+
877+static int drm_gem_object_info(char *buf, char **start, off_t offset,
878+ int request, int *eof, void *data)
879+{
880+ struct drm_minor *minor = (struct drm_minor *) data;
881+ struct drm_device *dev = minor->dev;
882+ int len = 0;
883+
884+ if (offset > DRM_PROC_LIMIT) {
885+ *eof = 1;
886+ return 0;
887+ }
888+
889+ *start = &buf[offset];
890+ *eof = 0;
891+ DRM_PROC_PRINT("%d objects\n", atomic_read(&dev->object_count));
892+ DRM_PROC_PRINT("%d object bytes\n", atomic_read(&dev->object_memory));
893+ DRM_PROC_PRINT("%d pinned\n", atomic_read(&dev->pin_count));
894+ DRM_PROC_PRINT("%d pin bytes\n", atomic_read(&dev->pin_memory));
895+ DRM_PROC_PRINT("%d gtt bytes\n", atomic_read(&dev->gtt_memory));
896+ DRM_PROC_PRINT("%d gtt total\n", dev->gtt_total);
897+ if (len > request + offset)
898+ return request;
899+ *eof = 1;
900+ return len - offset;
901+}
902+
903 #if DRM_DEBUG_CODE
904
905 static int drm__vma_info(char *buf, char **start, off_t offset, int request,
906diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c
907index c2f584f..82f4657 100644
908--- a/drivers/gpu/drm/drm_stub.c
909+++ b/drivers/gpu/drm/drm_stub.c
910@@ -152,6 +152,15 @@ static int drm_fill_in_dev(struct drm_device * dev, struct pci_dev *pdev,
911 goto error_out_unreg;
912 }
913
914+ if (driver->driver_features & DRIVER_GEM) {
915+ retcode = drm_gem_init(dev);
916+ if (retcode) {
917+ DRM_ERROR("Cannot initialize graphics execution "
918+ "manager (GEM)\n");
919+ goto error_out_unreg;
920+ }
921+ }
922+
923 return 0;
924
925 error_out_unreg:
926@@ -317,6 +326,7 @@ int drm_put_dev(struct drm_device * dev)
927 int drm_put_minor(struct drm_minor **minor_p)
928 {
929 struct drm_minor *minor = *minor_p;
930+
931 DRM_DEBUG("release secondary minor %d\n", minor->index);
932
933 if (minor->type == DRM_MINOR_LEGACY)
934diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
935index c4bbda6..5ba78e4 100644
936--- a/drivers/gpu/drm/i915/Makefile
937+++ b/drivers/gpu/drm/i915/Makefile
938@@ -4,7 +4,11 @@
939
940 ccflags-y := -Iinclude/drm
941 i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o i915_opregion.o \
942- i915_suspend.o
943+ i915_suspend.o \
944+ i915_gem.o \
945+ i915_gem_debug.o \
946+ i915_gem_proc.o \
947+ i915_gem_tiling.o
948
949 i915-$(CONFIG_COMPAT) += i915_ioc32.o
950
951diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
952index 8609ec2..3b5aa74 100644
953--- a/drivers/gpu/drm/i915/i915_dma.c
954+++ b/drivers/gpu/drm/i915/i915_dma.c
955@@ -170,24 +170,31 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
956 dev_priv->sarea_priv = (drm_i915_sarea_t *)
957 ((u8 *) dev_priv->sarea->handle + init->sarea_priv_offset);
958
959- dev_priv->ring.Start = init->ring_start;
960- dev_priv->ring.End = init->ring_end;
961- dev_priv->ring.Size = init->ring_size;
962- dev_priv->ring.tail_mask = dev_priv->ring.Size - 1;
963+ if (init->ring_size != 0) {
964+ if (dev_priv->ring.ring_obj != NULL) {
965+ i915_dma_cleanup(dev);
966+ DRM_ERROR("Client tried to initialize ringbuffer in "
967+ "GEM mode\n");
968+ return -EINVAL;
969+ }
970
971- dev_priv->ring.map.offset = init->ring_start;
972- dev_priv->ring.map.size = init->ring_size;
973- dev_priv->ring.map.type = 0;
974- dev_priv->ring.map.flags = 0;
975- dev_priv->ring.map.mtrr = 0;
976+ dev_priv->ring.Size = init->ring_size;
977+ dev_priv->ring.tail_mask = dev_priv->ring.Size - 1;
978
979- drm_core_ioremap(&dev_priv->ring.map, dev);
980+ dev_priv->ring.map.offset = init->ring_start;
981+ dev_priv->ring.map.size = init->ring_size;
982+ dev_priv->ring.map.type = 0;
983+ dev_priv->ring.map.flags = 0;
984+ dev_priv->ring.map.mtrr = 0;
985
986- if (dev_priv->ring.map.handle == NULL) {
987- i915_dma_cleanup(dev);
988- DRM_ERROR("can not ioremap virtual address for"
989- " ring buffer\n");
990- return -ENOMEM;
991+ drm_core_ioremap(&dev_priv->ring.map, dev);
992+
993+ if (dev_priv->ring.map.handle == NULL) {
994+ i915_dma_cleanup(dev);
995+ DRM_ERROR("can not ioremap virtual address for"
996+ " ring buffer\n");
997+ return -ENOMEM;
998+ }
999 }
1000
1001 dev_priv->ring.virtual_start = dev_priv->ring.map.handle;
1002@@ -377,9 +384,10 @@ static int i915_emit_cmds(struct drm_device * dev, int __user * buffer, int dwor
1003 return 0;
1004 }
1005
1006-static int i915_emit_box(struct drm_device * dev,
1007- struct drm_clip_rect __user * boxes,
1008- int i, int DR1, int DR4)
1009+int
1010+i915_emit_box(struct drm_device *dev,
1011+ struct drm_clip_rect __user *boxes,
1012+ int i, int DR1, int DR4)
1013 {
1014 drm_i915_private_t *dev_priv = dev->dev_private;
1015 struct drm_clip_rect box;
1016@@ -681,6 +689,9 @@ static int i915_getparam(struct drm_device *dev, void *data,
1017 case I915_PARAM_LAST_DISPATCH:
1018 value = READ_BREADCRUMB(dev_priv);
1019 break;
1020+ case I915_PARAM_HAS_GEM:
1021+ value = 1;
1022+ break;
1023 default:
1024 DRM_ERROR("Unknown parameter %d\n", param->param);
1025 return -EINVAL;
1026@@ -784,6 +795,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
1027 memset(dev_priv, 0, sizeof(drm_i915_private_t));
1028
1029 dev->dev_private = (void *)dev_priv;
1030+ dev_priv->dev = dev;
1031
1032 /* Add register map (needed for suspend/resume) */
1033 base = drm_get_resource_start(dev, mmio_bar);
1034@@ -793,6 +805,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
1035 _DRM_KERNEL | _DRM_DRIVER,
1036 &dev_priv->mmio_map);
1037
1038+ i915_gem_load(dev);
1039+
1040 /* Init HWS */
1041 if (!I915_NEED_GFX_HWS(dev)) {
1042 ret = i915_init_phys_hws(dev);
1043@@ -838,6 +852,25 @@ int i915_driver_unload(struct drm_device *dev)
1044 return 0;
1045 }
1046
1047+int i915_driver_open(struct drm_device *dev, struct drm_file *file_priv)
1048+{
1049+ struct drm_i915_file_private *i915_file_priv;
1050+
1051+ DRM_DEBUG("\n");
1052+ i915_file_priv = (struct drm_i915_file_private *)
1053+ drm_alloc(sizeof(*i915_file_priv), DRM_MEM_FILES);
1054+
1055+ if (!i915_file_priv)
1056+ return -ENOMEM;
1057+
1058+ file_priv->driver_priv = i915_file_priv;
1059+
1060+ i915_file_priv->mm.last_gem_seqno = 0;
1061+ i915_file_priv->mm.last_gem_throttle_seqno = 0;
1062+
1063+ return 0;
1064+}
1065+
1066 void i915_driver_lastclose(struct drm_device * dev)
1067 {
1068 drm_i915_private_t *dev_priv = dev->dev_private;
1069@@ -845,6 +878,8 @@ void i915_driver_lastclose(struct drm_device * dev)
1070 if (!dev_priv)
1071 return;
1072
1073+ i915_gem_lastclose(dev);
1074+
1075 if (dev_priv->agp_heap)
1076 i915_mem_takedown(&(dev_priv->agp_heap));
1077
1078@@ -857,6 +892,13 @@ void i915_driver_preclose(struct drm_device * dev, struct drm_file *file_priv)
1079 i915_mem_release(dev, file_priv, dev_priv->agp_heap);
1080 }
1081
1082+void i915_driver_postclose(struct drm_device *dev, struct drm_file *file_priv)
1083+{
1084+ struct drm_i915_file_private *i915_file_priv = file_priv->driver_priv;
1085+
1086+ drm_free(i915_file_priv, sizeof(*i915_file_priv), DRM_MEM_FILES);
1087+}
1088+
1089 struct drm_ioctl_desc i915_ioctls[] = {
1090 DRM_IOCTL_DEF(DRM_I915_INIT, i915_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
1091 DRM_IOCTL_DEF(DRM_I915_FLUSH, i915_flush_ioctl, DRM_AUTH),
1092@@ -875,6 +917,22 @@ struct drm_ioctl_desc i915_ioctls[] = {
1093 DRM_IOCTL_DEF(DRM_I915_GET_VBLANK_PIPE, i915_vblank_pipe_get, DRM_AUTH ),
1094 DRM_IOCTL_DEF(DRM_I915_VBLANK_SWAP, i915_vblank_swap, DRM_AUTH),
1095 DRM_IOCTL_DEF(DRM_I915_HWS_ADDR, i915_set_status_page, DRM_AUTH),
1096+ DRM_IOCTL_DEF(DRM_I915_GEM_INIT, i915_gem_init_ioctl, DRM_AUTH),
1097+ DRM_IOCTL_DEF(DRM_I915_GEM_EXECBUFFER, i915_gem_execbuffer, DRM_AUTH),
1098+ DRM_IOCTL_DEF(DRM_I915_GEM_PIN, i915_gem_pin_ioctl, DRM_AUTH|DRM_ROOT_ONLY),
1099+ DRM_IOCTL_DEF(DRM_I915_GEM_UNPIN, i915_gem_unpin_ioctl, DRM_AUTH|DRM_ROOT_ONLY),
1100+ DRM_IOCTL_DEF(DRM_I915_GEM_BUSY, i915_gem_busy_ioctl, DRM_AUTH),
1101+ DRM_IOCTL_DEF(DRM_I915_GEM_THROTTLE, i915_gem_throttle_ioctl, DRM_AUTH),
1102+ DRM_IOCTL_DEF(DRM_I915_GEM_ENTERVT, i915_gem_entervt_ioctl, DRM_AUTH),
1103+ DRM_IOCTL_DEF(DRM_I915_GEM_LEAVEVT, i915_gem_leavevt_ioctl, DRM_AUTH),
1104+ DRM_IOCTL_DEF(DRM_I915_GEM_CREATE, i915_gem_create_ioctl, 0),
1105+ DRM_IOCTL_DEF(DRM_I915_GEM_PREAD, i915_gem_pread_ioctl, 0),
1106+ DRM_IOCTL_DEF(DRM_I915_GEM_PWRITE, i915_gem_pwrite_ioctl, 0),
1107+ DRM_IOCTL_DEF(DRM_I915_GEM_MMAP, i915_gem_mmap_ioctl, 0),
1108+ DRM_IOCTL_DEF(DRM_I915_GEM_SET_DOMAIN, i915_gem_set_domain_ioctl, 0),
1109+ DRM_IOCTL_DEF(DRM_I915_GEM_SW_FINISH, i915_gem_sw_finish_ioctl, 0),
1110+ DRM_IOCTL_DEF(DRM_I915_GEM_SET_TILING, i915_gem_set_tiling, 0),
1111+ DRM_IOCTL_DEF(DRM_I915_GEM_GET_TILING, i915_gem_get_tiling, 0),
1112 };
1113
1114 int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls);
1115diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
1116index 37af03f..a80ead2 100644
1117--- a/drivers/gpu/drm/i915/i915_drv.c
1118+++ b/drivers/gpu/drm/i915/i915_drv.c
1119@@ -85,12 +85,15 @@ static struct drm_driver driver = {
1120 /* don't use mtrr's here, the Xserver or user space app should
1121 * deal with them for intel hardware.
1122 */
1123- .driver_features = DRIVER_USE_AGP | DRIVER_REQUIRE_AGP |
1124- DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED,
1125+ .driver_features =
1126+ DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | /* DRIVER_USE_MTRR |*/
1127+ DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM,
1128 .load = i915_driver_load,
1129 .unload = i915_driver_unload,
1130+ .open = i915_driver_open,
1131 .lastclose = i915_driver_lastclose,
1132 .preclose = i915_driver_preclose,
1133+ .postclose = i915_driver_postclose,
1134 .suspend = i915_suspend,
1135 .resume = i915_resume,
1136 .device_is_agp = i915_driver_device_is_agp,
1137@@ -104,6 +107,10 @@ static struct drm_driver driver = {
1138 .reclaim_buffers = drm_core_reclaim_buffers,
1139 .get_map_ofs = drm_core_get_map_ofs,
1140 .get_reg_ofs = drm_core_get_reg_ofs,
1141+ .proc_init = i915_gem_proc_init,
1142+ .proc_cleanup = i915_gem_proc_cleanup,
1143+ .gem_init_object = i915_gem_init_object,
1144+ .gem_free_object = i915_gem_free_object,
1145 .ioctls = i915_ioctls,
1146 .fops = {
1147 .owner = THIS_MODULE,
1148diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
1149index d1a02be..87b071a 100644
1150--- a/drivers/gpu/drm/i915/i915_drv.h
1151+++ b/drivers/gpu/drm/i915/i915_drv.h
1152@@ -39,7 +39,7 @@
1153
1154 #define DRIVER_NAME "i915"
1155 #define DRIVER_DESC "Intel Graphics"
1156-#define DRIVER_DATE "20060119"
1157+#define DRIVER_DATE "20080730"
1158
1159 enum pipe {
1160 PIPE_A = 0,
1161@@ -60,16 +60,23 @@ enum pipe {
1162 #define DRIVER_MINOR 6
1163 #define DRIVER_PATCHLEVEL 0
1164
1165+#define WATCH_COHERENCY 0
1166+#define WATCH_BUF 0
1167+#define WATCH_EXEC 0
1168+#define WATCH_LRU 0
1169+#define WATCH_RELOC 0
1170+#define WATCH_INACTIVE 0
1171+#define WATCH_PWRITE 0
1172+
1173 typedef struct _drm_i915_ring_buffer {
1174 int tail_mask;
1175- unsigned long Start;
1176- unsigned long End;
1177 unsigned long Size;
1178 u8 *virtual_start;
1179 int head;
1180 int tail;
1181 int space;
1182 drm_local_map_t map;
1183+ struct drm_gem_object *ring_obj;
1184 } drm_i915_ring_buffer_t;
1185
1186 struct mem_block {
1187@@ -101,6 +108,8 @@ struct intel_opregion {
1188 };
1189
1190 typedef struct drm_i915_private {
1191+ struct drm_device *dev;
1192+
1193 drm_local_map_t *sarea;
1194 drm_local_map_t *mmio_map;
1195
1196@@ -113,6 +122,7 @@ typedef struct drm_i915_private {
1197 uint32_t counter;
1198 unsigned int status_gfx_addr;
1199 drm_local_map_t hws_map;
1200+ struct drm_gem_object *hws_obj;
1201
1202 unsigned int cpp;
1203 int back_offset;
1204@@ -122,7 +132,6 @@ typedef struct drm_i915_private {
1205
1206 wait_queue_head_t irq_queue;
1207 atomic_t irq_received;
1208- atomic_t irq_emitted;
1209 /** Protects user_irq_refcount and irq_mask_reg */
1210 spinlock_t user_irq_lock;
1211 /** Refcount for i915_user_irq_get() versus i915_user_irq_put(). */
1212@@ -230,8 +239,174 @@ typedef struct drm_i915_private {
1213 u8 saveDACMASK;
1214 u8 saveDACDATA[256*3]; /* 256 3-byte colors */
1215 u8 saveCR[37];
1216+
1217+ struct {
1218+ struct drm_mm gtt_space;
1219+
1220+ /**
1221+ * List of objects currently involved in rendering from the
1222+ * ringbuffer.
1223+ *
1224+ * A reference is held on the buffer while on this list.
1225+ */
1226+ struct list_head active_list;
1227+
1228+ /**
1229+ * List of objects which are not in the ringbuffer but which
1230+ * still have a write_domain which needs to be flushed before
1231+ * unbinding.
1232+ *
1233+ * A reference is held on the buffer while on this list.
1234+ */
1235+ struct list_head flushing_list;
1236+
1237+ /**
1238+ * LRU list of objects which are not in the ringbuffer and
1239+ * are ready to unbind, but are still in the GTT.
1240+ *
1241+ * A reference is not held on the buffer while on this list,
1242+ * as merely being GTT-bound shouldn't prevent its being
1243+ * freed, and we'll pull it off the list in the free path.
1244+ */
1245+ struct list_head inactive_list;
1246+
1247+ /**
1248+ * List of breadcrumbs associated with GPU requests currently
1249+ * outstanding.
1250+ */
1251+ struct list_head request_list;
1252+
1253+ /**
1254+ * We leave the user IRQ off as much as possible,
1255+ * but this means that requests will finish and never
1256+ * be retired once the system goes idle. Set a timer to
1257+ * fire periodically while the ring is running. When it
1258+ * fires, go retire requests.
1259+ */
1260+ struct delayed_work retire_work;
1261+
1262+ uint32_t next_gem_seqno;
1263+
1264+ /**
1265+ * Waiting sequence number, if any
1266+ */
1267+ uint32_t waiting_gem_seqno;
1268+
1269+ /**
1270+ * Last seq seen at irq time
1271+ */
1272+ uint32_t irq_gem_seqno;
1273+
1274+ /**
1275+ * Flag if the X Server, and thus DRM, is not currently in
1276+ * control of the device.
1277+ *
1278+ * This is set between LeaveVT and EnterVT. It needs to be
1279+ * replaced with a semaphore. It also needs to be
1280+ * transitioned away from for kernel modesetting.
1281+ */
1282+ int suspended;
1283+
1284+ /**
1285+ * Flag if the hardware appears to be wedged.
1286+ *
1287+ * This is set when attempts to idle the device timeout.
1288+ * It prevents command submission from occuring and makes
1289+ * every pending request fail
1290+ */
1291+ int wedged;
1292+
1293+ /** Bit 6 swizzling required for X tiling */
1294+ uint32_t bit_6_swizzle_x;
1295+ /** Bit 6 swizzling required for Y tiling */
1296+ uint32_t bit_6_swizzle_y;
1297+ } mm;
1298 } drm_i915_private_t;
1299
1300+/** driver private structure attached to each drm_gem_object */
1301+struct drm_i915_gem_object {
1302+ struct drm_gem_object *obj;
1303+
1304+ /** Current space allocated to this object in the GTT, if any. */
1305+ struct drm_mm_node *gtt_space;
1306+
1307+ /** This object's place on the active/flushing/inactive lists */
1308+ struct list_head list;
1309+
1310+ /**
1311+ * This is set if the object is on the active or flushing lists
1312+ * (has pending rendering), and is not set if it's on inactive (ready
1313+ * to be unbound).
1314+ */
1315+ int active;
1316+
1317+ /**
1318+ * This is set if the object has been written to since last bound
1319+ * to the GTT
1320+ */
1321+ int dirty;
1322+
1323+ /** AGP memory structure for our GTT binding. */
1324+ DRM_AGP_MEM *agp_mem;
1325+
1326+ struct page **page_list;
1327+
1328+ /**
1329+ * Current offset of the object in GTT space.
1330+ *
1331+ * This is the same as gtt_space->start
1332+ */
1333+ uint32_t gtt_offset;
1334+
1335+ /** Boolean whether this object has a valid gtt offset. */
1336+ int gtt_bound;
1337+
1338+ /** How many users have pinned this object in GTT space */
1339+ int pin_count;
1340+
1341+ /** Breadcrumb of last rendering to the buffer. */
1342+ uint32_t last_rendering_seqno;
1343+
1344+ /** Current tiling mode for the object. */
1345+ uint32_t tiling_mode;
1346+
1347+ /**
1348+ * Flagging of which individual pages are valid in GEM_DOMAIN_CPU when
1349+ * GEM_DOMAIN_CPU is not in the object's read domain.
1350+ */
1351+ uint8_t *page_cpu_valid;
1352+};
1353+
1354+/**
1355+ * Request queue structure.
1356+ *
1357+ * The request queue allows us to note sequence numbers that have been emitted
1358+ * and may be associated with active buffers to be retired.
1359+ *
1360+ * By keeping this list, we can avoid having to do questionable
1361+ * sequence-number comparisons on buffer last_rendering_seqnos, and associate
1362+ * an emission time with seqnos for tracking how far ahead of the GPU we are.
1363+ */
1364+struct drm_i915_gem_request {
1365+ /** GEM sequence number associated with this request. */
1366+ uint32_t seqno;
1367+
1368+ /** Time at which this request was emitted, in jiffies. */
1369+ unsigned long emitted_jiffies;
1370+
1371+ /** Cache domains that were flushed at the start of the request. */
1372+ uint32_t flush_domains;
1373+
1374+ struct list_head list;
1375+};
1376+
1377+struct drm_i915_file_private {
1378+ struct {
1379+ uint32_t last_gem_seqno;
1380+ uint32_t last_gem_throttle_seqno;
1381+ } mm;
1382+};
1383+
1384 extern struct drm_ioctl_desc i915_ioctls[];
1385 extern int i915_max_ioctl;
1386
1387@@ -239,18 +414,26 @@ extern int i915_max_ioctl;
1388 extern void i915_kernel_lost_context(struct drm_device * dev);
1389 extern int i915_driver_load(struct drm_device *, unsigned long flags);
1390 extern int i915_driver_unload(struct drm_device *);
1391+extern int i915_driver_open(struct drm_device *dev, struct drm_file *file_priv);
1392 extern void i915_driver_lastclose(struct drm_device * dev);
1393 extern void i915_driver_preclose(struct drm_device *dev,
1394 struct drm_file *file_priv);
1395+extern void i915_driver_postclose(struct drm_device *dev,
1396+ struct drm_file *file_priv);
1397 extern int i915_driver_device_is_agp(struct drm_device * dev);
1398 extern long i915_compat_ioctl(struct file *filp, unsigned int cmd,
1399 unsigned long arg);
1400+extern int i915_emit_box(struct drm_device *dev,
1401+ struct drm_clip_rect __user *boxes,
1402+ int i, int DR1, int DR4);
1403
1404 /* i915_irq.c */
1405 extern int i915_irq_emit(struct drm_device *dev, void *data,
1406 struct drm_file *file_priv);
1407 extern int i915_irq_wait(struct drm_device *dev, void *data,
1408 struct drm_file *file_priv);
1409+void i915_user_irq_get(struct drm_device *dev);
1410+void i915_user_irq_put(struct drm_device *dev);
1411
1412 extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS);
1413 extern void i915_driver_irq_preinstall(struct drm_device * dev);
1414@@ -279,6 +462,67 @@ extern int i915_mem_destroy_heap(struct drm_device *dev, void *data,
1415 extern void i915_mem_takedown(struct mem_block **heap);
1416 extern void i915_mem_release(struct drm_device * dev,
1417 struct drm_file *file_priv, struct mem_block *heap);
1418+/* i915_gem.c */
1419+int i915_gem_init_ioctl(struct drm_device *dev, void *data,
1420+ struct drm_file *file_priv);
1421+int i915_gem_create_ioctl(struct drm_device *dev, void *data,
1422+ struct drm_file *file_priv);
1423+int i915_gem_pread_ioctl(struct drm_device *dev, void *data,
1424+ struct drm_file *file_priv);
1425+int i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
1426+ struct drm_file *file_priv);
1427+int i915_gem_mmap_ioctl(struct drm_device *dev, void *data,
1428+ struct drm_file *file_priv);
1429+int i915_gem_set_domain_ioctl(struct drm_device *dev, void *data,
1430+ struct drm_file *file_priv);
1431+int i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data,
1432+ struct drm_file *file_priv);
1433+int i915_gem_execbuffer(struct drm_device *dev, void *data,
1434+ struct drm_file *file_priv);
1435+int i915_gem_pin_ioctl(struct drm_device *dev, void *data,
1436+ struct drm_file *file_priv);
1437+int i915_gem_unpin_ioctl(struct drm_device *dev, void *data,
1438+ struct drm_file *file_priv);
1439+int i915_gem_busy_ioctl(struct drm_device *dev, void *data,
1440+ struct drm_file *file_priv);
1441+int i915_gem_throttle_ioctl(struct drm_device *dev, void *data,
1442+ struct drm_file *file_priv);
1443+int i915_gem_entervt_ioctl(struct drm_device *dev, void *data,
1444+ struct drm_file *file_priv);
1445+int i915_gem_leavevt_ioctl(struct drm_device *dev, void *data,
1446+ struct drm_file *file_priv);
1447+int i915_gem_set_tiling(struct drm_device *dev, void *data,
1448+ struct drm_file *file_priv);
1449+int i915_gem_get_tiling(struct drm_device *dev, void *data,
1450+ struct drm_file *file_priv);
1451+void i915_gem_load(struct drm_device *dev);
1452+int i915_gem_proc_init(struct drm_minor *minor);
1453+void i915_gem_proc_cleanup(struct drm_minor *minor);
1454+int i915_gem_init_object(struct drm_gem_object *obj);
1455+void i915_gem_free_object(struct drm_gem_object *obj);
1456+int i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment);
1457+void i915_gem_object_unpin(struct drm_gem_object *obj);
1458+void i915_gem_lastclose(struct drm_device *dev);
1459+uint32_t i915_get_gem_seqno(struct drm_device *dev);
1460+void i915_gem_retire_requests(struct drm_device *dev);
1461+void i915_gem_retire_work_handler(struct work_struct *work);
1462+void i915_gem_clflush_object(struct drm_gem_object *obj);
1463+
1464+/* i915_gem_tiling.c */
1465+void i915_gem_detect_bit_6_swizzle(struct drm_device *dev);
1466+
1467+/* i915_gem_debug.c */
1468+void i915_gem_dump_object(struct drm_gem_object *obj, int len,
1469+ const char *where, uint32_t mark);
1470+#if WATCH_INACTIVE
1471+void i915_verify_inactive(struct drm_device *dev, char *file, int line);
1472+#else
1473+#define i915_verify_inactive(dev, file, line)
1474+#endif
1475+void i915_gem_object_check_coherency(struct drm_gem_object *obj, int handle);
1476+void i915_gem_dump_object(struct drm_gem_object *obj, int len,
1477+ const char *where, uint32_t mark);
1478+void i915_dump_lru(struct drm_device *dev, const char *where);
1479
1480 /* i915_suspend.c */
1481 extern int i915_save_state(struct drm_device *dev);
1482@@ -347,6 +591,7 @@ extern void opregion_enable_asle(struct drm_device *dev);
1483 */
1484 #define READ_HWSP(dev_priv, reg) (((volatile u32*)(dev_priv->hw_status_page))[reg])
1485 #define READ_BREADCRUMB(dev_priv) READ_HWSP(dev_priv, 5)
1486+#define I915_GEM_HWS_INDEX 0x10
1487
1488 extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
1489
1490diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
1491new file mode 100644
1492index 0000000..90ae8a0
1493--- /dev/null
1494+++ b/drivers/gpu/drm/i915/i915_gem.c
1495@@ -0,0 +1,2497 @@
1496+/*
1497+ * Copyright © 2008 Intel Corporation
1498+ *
1499+ * Permission is hereby granted, free of charge, to any person obtaining a
1500+ * copy of this software and associated documentation files (the "Software"),
1501+ * to deal in the Software without restriction, including without limitation
1502+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
1503+ * and/or sell copies of the Software, and to permit persons to whom the
1504+ * Software is furnished to do so, subject to the following conditions:
1505+ *
1506+ * The above copyright notice and this permission notice (including the next
1507+ * paragraph) shall be included in all copies or substantial portions of the
1508+ * Software.
1509+ *
1510+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1511+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1512+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
1513+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1514+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
1515+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
1516+ * IN THE SOFTWARE.
1517+ *
1518+ * Authors:
1519+ * Eric Anholt <eric@anholt.net>
1520+ *
1521+ */
1522+
1523+#include "drmP.h"
1524+#include "drm.h"
1525+#include "i915_drm.h"
1526+#include "i915_drv.h"
1527+#include <linux/swap.h>
1528+
1529+static int
1530+i915_gem_object_set_domain(struct drm_gem_object *obj,
1531+ uint32_t read_domains,
1532+ uint32_t write_domain);
1533+static int
1534+i915_gem_object_set_domain_range(struct drm_gem_object *obj,
1535+ uint64_t offset,
1536+ uint64_t size,
1537+ uint32_t read_domains,
1538+ uint32_t write_domain);
1539+static int
1540+i915_gem_set_domain(struct drm_gem_object *obj,
1541+ struct drm_file *file_priv,
1542+ uint32_t read_domains,
1543+ uint32_t write_domain);
1544+static int i915_gem_object_get_page_list(struct drm_gem_object *obj);
1545+static void i915_gem_object_free_page_list(struct drm_gem_object *obj);
1546+static int i915_gem_object_wait_rendering(struct drm_gem_object *obj);
1547+
1548+int
1549+i915_gem_init_ioctl(struct drm_device *dev, void *data,
1550+ struct drm_file *file_priv)
1551+{
1552+ drm_i915_private_t *dev_priv = dev->dev_private;
1553+ struct drm_i915_gem_init *args = data;
1554+
1555+ mutex_lock(&dev->struct_mutex);
1556+
1557+ if (args->gtt_start >= args->gtt_end ||
1558+ (args->gtt_start & (PAGE_SIZE - 1)) != 0 ||
1559+ (args->gtt_end & (PAGE_SIZE - 1)) != 0) {
1560+ mutex_unlock(&dev->struct_mutex);
1561+ return -EINVAL;
1562+ }
1563+
1564+ drm_mm_init(&dev_priv->mm.gtt_space, args->gtt_start,
1565+ args->gtt_end - args->gtt_start);
1566+
1567+ dev->gtt_total = (uint32_t) (args->gtt_end - args->gtt_start);
1568+
1569+ mutex_unlock(&dev->struct_mutex);
1570+
1571+ return 0;
1572+}
1573+
1574+
1575+/**
1576+ * Creates a new mm object and returns a handle to it.
1577+ */
1578+int
1579+i915_gem_create_ioctl(struct drm_device *dev, void *data,
1580+ struct drm_file *file_priv)
1581+{
1582+ struct drm_i915_gem_create *args = data;
1583+ struct drm_gem_object *obj;
1584+ int handle, ret;
1585+
1586+ args->size = roundup(args->size, PAGE_SIZE);
1587+
1588+ /* Allocate the new object */
1589+ obj = drm_gem_object_alloc(dev, args->size);
1590+ if (obj == NULL)
1591+ return -ENOMEM;
1592+
1593+ ret = drm_gem_handle_create(file_priv, obj, &handle);
1594+ mutex_lock(&dev->struct_mutex);
1595+ drm_gem_object_handle_unreference(obj);
1596+ mutex_unlock(&dev->struct_mutex);
1597+
1598+ if (ret)
1599+ return ret;
1600+
1601+ args->handle = handle;
1602+
1603+ return 0;
1604+}
1605+
1606+/**
1607+ * Reads data from the object referenced by handle.
1608+ *
1609+ * On error, the contents of *data are undefined.
1610+ */
1611+int
1612+i915_gem_pread_ioctl(struct drm_device *dev, void *data,
1613+ struct drm_file *file_priv)
1614+{
1615+ struct drm_i915_gem_pread *args = data;
1616+ struct drm_gem_object *obj;
1617+ struct drm_i915_gem_object *obj_priv;
1618+ ssize_t read;
1619+ loff_t offset;
1620+ int ret;
1621+
1622+ obj = drm_gem_object_lookup(dev, file_priv, args->handle);
1623+ if (obj == NULL)
1624+ return -EBADF;
1625+ obj_priv = obj->driver_private;
1626+
1627+ /* Bounds check source.
1628+ *
1629+ * XXX: This could use review for overflow issues...
1630+ */
1631+ if (args->offset > obj->size || args->size > obj->size ||
1632+ args->offset + args->size > obj->size) {
1633+ drm_gem_object_unreference(obj);
1634+ return -EINVAL;
1635+ }
1636+
1637+ mutex_lock(&dev->struct_mutex);
1638+
1639+ ret = i915_gem_object_set_domain_range(obj, args->offset, args->size,
1640+ I915_GEM_DOMAIN_CPU, 0);
1641+ if (ret != 0) {
1642+ drm_gem_object_unreference(obj);
1643+ mutex_unlock(&dev->struct_mutex);
1644+ }
1645+
1646+ offset = args->offset;
1647+
1648+ read = vfs_read(obj->filp, (char __user *)(uintptr_t)args->data_ptr,
1649+ args->size, &offset);
1650+ if (read != args->size) {
1651+ drm_gem_object_unreference(obj);
1652+ mutex_unlock(&dev->struct_mutex);
1653+ if (read < 0)
1654+ return read;
1655+ else
1656+ return -EINVAL;
1657+ }
1658+
1659+ drm_gem_object_unreference(obj);
1660+ mutex_unlock(&dev->struct_mutex);
1661+
1662+ return 0;
1663+}
1664+
1665+static int
1666+i915_gem_gtt_pwrite(struct drm_device *dev, struct drm_gem_object *obj,
1667+ struct drm_i915_gem_pwrite *args,
1668+ struct drm_file *file_priv)
1669+{
1670+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
1671+ ssize_t remain;
1672+ loff_t offset;
1673+ char __user *user_data;
1674+ char *vaddr;
1675+ int i, o, l;
1676+ int ret = 0;
1677+ unsigned long pfn;
1678+ unsigned long unwritten;
1679+
1680+ user_data = (char __user *) (uintptr_t) args->data_ptr;
1681+ remain = args->size;
1682+ if (!access_ok(VERIFY_READ, user_data, remain))
1683+ return -EFAULT;
1684+
1685+
1686+ mutex_lock(&dev->struct_mutex);
1687+ ret = i915_gem_object_pin(obj, 0);
1688+ if (ret) {
1689+ mutex_unlock(&dev->struct_mutex);
1690+ return ret;
1691+ }
1692+ ret = i915_gem_set_domain(obj, file_priv,
1693+ I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
1694+ if (ret)
1695+ goto fail;
1696+
1697+ obj_priv = obj->driver_private;
1698+ offset = obj_priv->gtt_offset + args->offset;
1699+ obj_priv->dirty = 1;
1700+
1701+ while (remain > 0) {
1702+ /* Operation in this page
1703+ *
1704+ * i = page number
1705+ * o = offset within page
1706+ * l = bytes to copy
1707+ */
1708+ i = offset >> PAGE_SHIFT;
1709+ o = offset & (PAGE_SIZE-1);
1710+ l = remain;
1711+ if ((o + l) > PAGE_SIZE)
1712+ l = PAGE_SIZE - o;
1713+
1714+ pfn = (dev->agp->base >> PAGE_SHIFT) + i;
1715+
1716+#ifdef CONFIG_HIGHMEM
1717+ /* kmap_atomic can't map IO pages on non-HIGHMEM kernels
1718+ */
1719+ vaddr = kmap_atomic_pfn(pfn, KM_USER0);
1720+#if WATCH_PWRITE
1721+ DRM_INFO("pwrite i %d o %d l %d pfn %ld vaddr %p\n",
1722+ i, o, l, pfn, vaddr);
1723+#endif
1724+ unwritten = __copy_from_user_inatomic_nocache(vaddr + o,
1725+ user_data, l);
1726+ kunmap_atomic(vaddr, KM_USER0);
1727+
1728+ if (unwritten)
1729+#endif /* CONFIG_HIGHMEM */
1730+ {
1731+ vaddr = ioremap(pfn << PAGE_SHIFT, PAGE_SIZE);
1732+#if WATCH_PWRITE
1733+ DRM_INFO("pwrite slow i %d o %d l %d "
1734+ "pfn %ld vaddr %p\n",
1735+ i, o, l, pfn, vaddr);
1736+#endif
1737+ if (vaddr == NULL) {
1738+ ret = -EFAULT;
1739+ goto fail;
1740+ }
1741+ unwritten = __copy_from_user(vaddr + o, user_data, l);
1742+#if WATCH_PWRITE
1743+ DRM_INFO("unwritten %ld\n", unwritten);
1744+#endif
1745+ iounmap(vaddr);
1746+ if (unwritten) {
1747+ ret = -EFAULT;
1748+ goto fail;
1749+ }
1750+ }
1751+
1752+ remain -= l;
1753+ user_data += l;
1754+ offset += l;
1755+ }
1756+#if WATCH_PWRITE && 1
1757+ i915_gem_clflush_object(obj);
1758+ i915_gem_dump_object(obj, args->offset + args->size, __func__, ~0);
1759+ i915_gem_clflush_object(obj);
1760+#endif
1761+
1762+fail:
1763+ i915_gem_object_unpin(obj);
1764+ mutex_unlock(&dev->struct_mutex);
1765+
1766+ return ret;
1767+}
1768+
1769+int
1770+i915_gem_shmem_pwrite(struct drm_device *dev, struct drm_gem_object *obj,
1771+ struct drm_i915_gem_pwrite *args,
1772+ struct drm_file *file_priv)
1773+{
1774+ int ret;
1775+ loff_t offset;
1776+ ssize_t written;
1777+
1778+ mutex_lock(&dev->struct_mutex);
1779+
1780+ ret = i915_gem_set_domain(obj, file_priv,
1781+ I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
1782+ if (ret) {
1783+ mutex_unlock(&dev->struct_mutex);
1784+ return ret;
1785+ }
1786+
1787+ offset = args->offset;
1788+
1789+ written = vfs_write(obj->filp,
1790+ (char __user *)(uintptr_t) args->data_ptr,
1791+ args->size, &offset);
1792+ if (written != args->size) {
1793+ mutex_unlock(&dev->struct_mutex);
1794+ if (written < 0)
1795+ return written;
1796+ else
1797+ return -EINVAL;
1798+ }
1799+
1800+ mutex_unlock(&dev->struct_mutex);
1801+
1802+ return 0;
1803+}
1804+
1805+/**
1806+ * Writes data to the object referenced by handle.
1807+ *
1808+ * On error, the contents of the buffer that were to be modified are undefined.
1809+ */
1810+int
1811+i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
1812+ struct drm_file *file_priv)
1813+{
1814+ struct drm_i915_gem_pwrite *args = data;
1815+ struct drm_gem_object *obj;
1816+ struct drm_i915_gem_object *obj_priv;
1817+ int ret = 0;
1818+
1819+ obj = drm_gem_object_lookup(dev, file_priv, args->handle);
1820+ if (obj == NULL)
1821+ return -EBADF;
1822+ obj_priv = obj->driver_private;
1823+
1824+ /* Bounds check destination.
1825+ *
1826+ * XXX: This could use review for overflow issues...
1827+ */
1828+ if (args->offset > obj->size || args->size > obj->size ||
1829+ args->offset + args->size > obj->size) {
1830+ drm_gem_object_unreference(obj);
1831+ return -EINVAL;
1832+ }
1833+
1834+ /* We can only do the GTT pwrite on untiled buffers, as otherwise
1835+ * it would end up going through the fenced access, and we'll get
1836+ * different detiling behavior between reading and writing.
1837+ * pread/pwrite currently are reading and writing from the CPU
1838+ * perspective, requiring manual detiling by the client.
1839+ */
1840+ if (obj_priv->tiling_mode == I915_TILING_NONE &&
1841+ dev->gtt_total != 0)
1842+ ret = i915_gem_gtt_pwrite(dev, obj, args, file_priv);
1843+ else
1844+ ret = i915_gem_shmem_pwrite(dev, obj, args, file_priv);
1845+
1846+#if WATCH_PWRITE
1847+ if (ret)
1848+ DRM_INFO("pwrite failed %d\n", ret);
1849+#endif
1850+
1851+ drm_gem_object_unreference(obj);
1852+
1853+ return ret;
1854+}
1855+
1856+/**
1857+ * Called when user space prepares to use an object
1858+ */
1859+int
1860+i915_gem_set_domain_ioctl(struct drm_device *dev, void *data,
1861+ struct drm_file *file_priv)
1862+{
1863+ struct drm_i915_gem_set_domain *args = data;
1864+ struct drm_gem_object *obj;
1865+ int ret;
1866+
1867+ if (!(dev->driver->driver_features & DRIVER_GEM))
1868+ return -ENODEV;
1869+
1870+ obj = drm_gem_object_lookup(dev, file_priv, args->handle);
1871+ if (obj == NULL)
1872+ return -EBADF;
1873+
1874+ mutex_lock(&dev->struct_mutex);
1875+#if WATCH_BUF
1876+ DRM_INFO("set_domain_ioctl %p(%d), %08x %08x\n",
1877+ obj, obj->size, args->read_domains, args->write_domain);
1878+#endif
1879+ ret = i915_gem_set_domain(obj, file_priv,
1880+ args->read_domains, args->write_domain);
1881+ drm_gem_object_unreference(obj);
1882+ mutex_unlock(&dev->struct_mutex);
1883+ return ret;
1884+}
1885+
1886+/**
1887+ * Called when user space has done writes to this buffer
1888+ */
1889+int
1890+i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data,
1891+ struct drm_file *file_priv)
1892+{
1893+ struct drm_i915_gem_sw_finish *args = data;
1894+ struct drm_gem_object *obj;
1895+ struct drm_i915_gem_object *obj_priv;
1896+ int ret = 0;
1897+
1898+ if (!(dev->driver->driver_features & DRIVER_GEM))
1899+ return -ENODEV;
1900+
1901+ mutex_lock(&dev->struct_mutex);
1902+ obj = drm_gem_object_lookup(dev, file_priv, args->handle);
1903+ if (obj == NULL) {
1904+ mutex_unlock(&dev->struct_mutex);
1905+ return -EBADF;
1906+ }
1907+
1908+#if WATCH_BUF
1909+ DRM_INFO("%s: sw_finish %d (%p %d)\n",
1910+ __func__, args->handle, obj, obj->size);
1911+#endif
1912+ obj_priv = obj->driver_private;
1913+
1914+ /* Pinned buffers may be scanout, so flush the cache */
1915+ if ((obj->write_domain & I915_GEM_DOMAIN_CPU) && obj_priv->pin_count) {
1916+ i915_gem_clflush_object(obj);
1917+ drm_agp_chipset_flush(dev);
1918+ }
1919+ drm_gem_object_unreference(obj);
1920+ mutex_unlock(&dev->struct_mutex);
1921+ return ret;
1922+}
1923+
1924+/**
1925+ * Maps the contents of an object, returning the address it is mapped
1926+ * into.
1927+ *
1928+ * While the mapping holds a reference on the contents of the object, it doesn't
1929+ * imply a ref on the object itself.
1930+ */
1931+int
1932+i915_gem_mmap_ioctl(struct drm_device *dev, void *data,
1933+ struct drm_file *file_priv)
1934+{
1935+ struct drm_i915_gem_mmap *args = data;
1936+ struct drm_gem_object *obj;
1937+ loff_t offset;
1938+ unsigned long addr;
1939+
1940+ if (!(dev->driver->driver_features & DRIVER_GEM))
1941+ return -ENODEV;
1942+
1943+ obj = drm_gem_object_lookup(dev, file_priv, args->handle);
1944+ if (obj == NULL)
1945+ return -EBADF;
1946+
1947+ offset = args->offset;
1948+
1949+ down_write(&current->mm->mmap_sem);
1950+ addr = do_mmap(obj->filp, 0, args->size,
1951+ PROT_READ | PROT_WRITE, MAP_SHARED,
1952+ args->offset);
1953+ up_write(&current->mm->mmap_sem);
1954+ mutex_lock(&dev->struct_mutex);
1955+ drm_gem_object_unreference(obj);
1956+ mutex_unlock(&dev->struct_mutex);
1957+ if (IS_ERR((void *)addr))
1958+ return addr;
1959+
1960+ args->addr_ptr = (uint64_t) addr;
1961+
1962+ return 0;
1963+}
1964+
1965+static void
1966+i915_gem_object_free_page_list(struct drm_gem_object *obj)
1967+{
1968+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
1969+ int page_count = obj->size / PAGE_SIZE;
1970+ int i;
1971+
1972+ if (obj_priv->page_list == NULL)
1973+ return;
1974+
1975+
1976+ for (i = 0; i < page_count; i++)
1977+ if (obj_priv->page_list[i] != NULL) {
1978+ if (obj_priv->dirty)
1979+ set_page_dirty(obj_priv->page_list[i]);
1980+ mark_page_accessed(obj_priv->page_list[i]);
1981+ page_cache_release(obj_priv->page_list[i]);
1982+ }
1983+ obj_priv->dirty = 0;
1984+
1985+ drm_free(obj_priv->page_list,
1986+ page_count * sizeof(struct page *),
1987+ DRM_MEM_DRIVER);
1988+ obj_priv->page_list = NULL;
1989+}
1990+
1991+static void
1992+i915_gem_object_move_to_active(struct drm_gem_object *obj)
1993+{
1994+ struct drm_device *dev = obj->dev;
1995+ drm_i915_private_t *dev_priv = dev->dev_private;
1996+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
1997+
1998+ /* Add a reference if we're newly entering the active list. */
1999+ if (!obj_priv->active) {
2000+ drm_gem_object_reference(obj);
2001+ obj_priv->active = 1;
2002+ }
2003+ /* Move from whatever list we were on to the tail of execution. */
2004+ list_move_tail(&obj_priv->list,
2005+ &dev_priv->mm.active_list);
2006+}
2007+
2008+
2009+static void
2010+i915_gem_object_move_to_inactive(struct drm_gem_object *obj)
2011+{
2012+ struct drm_device *dev = obj->dev;
2013+ drm_i915_private_t *dev_priv = dev->dev_private;
2014+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
2015+
2016+ i915_verify_inactive(dev, __FILE__, __LINE__);
2017+ if (obj_priv->pin_count != 0)
2018+ list_del_init(&obj_priv->list);
2019+ else
2020+ list_move_tail(&obj_priv->list, &dev_priv->mm.inactive_list);
2021+
2022+ if (obj_priv->active) {
2023+ obj_priv->active = 0;
2024+ drm_gem_object_unreference(obj);
2025+ }
2026+ i915_verify_inactive(dev, __FILE__, __LINE__);
2027+}
2028+
2029+/**
2030+ * Creates a new sequence number, emitting a write of it to the status page
2031+ * plus an interrupt, which will trigger i915_user_interrupt_handler.
2032+ *
2033+ * Must be called with struct_lock held.
2034+ *
2035+ * Returned sequence numbers are nonzero on success.
2036+ */
2037+static uint32_t
2038+i915_add_request(struct drm_device *dev, uint32_t flush_domains)
2039+{
2040+ drm_i915_private_t *dev_priv = dev->dev_private;
2041+ struct drm_i915_gem_request *request;
2042+ uint32_t seqno;
2043+ int was_empty;
2044+ RING_LOCALS;
2045+
2046+ request = drm_calloc(1, sizeof(*request), DRM_MEM_DRIVER);
2047+ if (request == NULL)
2048+ return 0;
2049+
2050+ /* Grab the seqno we're going to make this request be, and bump the
2051+ * next (skipping 0 so it can be the reserved no-seqno value).
2052+ */
2053+ seqno = dev_priv->mm.next_gem_seqno;
2054+ dev_priv->mm.next_gem_seqno++;
2055+ if (dev_priv->mm.next_gem_seqno == 0)
2056+ dev_priv->mm.next_gem_seqno++;
2057+
2058+ BEGIN_LP_RING(4);
2059+ OUT_RING(MI_STORE_DWORD_INDEX);
2060+ OUT_RING(I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
2061+ OUT_RING(seqno);
2062+
2063+ OUT_RING(MI_USER_INTERRUPT);
2064+ ADVANCE_LP_RING();
2065+
2066+ DRM_DEBUG("%d\n", seqno);
2067+
2068+ request->seqno = seqno;
2069+ request->emitted_jiffies = jiffies;
2070+ request->flush_domains = flush_domains;
2071+ was_empty = list_empty(&dev_priv->mm.request_list);
2072+ list_add_tail(&request->list, &dev_priv->mm.request_list);
2073+
2074+ if (was_empty)
2075+ schedule_delayed_work(&dev_priv->mm.retire_work, HZ);
2076+ return seqno;
2077+}
2078+
2079+/**
2080+ * Command execution barrier
2081+ *
2082+ * Ensures that all commands in the ring are finished
2083+ * before signalling the CPU
2084+ */
2085+uint32_t
2086+i915_retire_commands(struct drm_device *dev)
2087+{
2088+ drm_i915_private_t *dev_priv = dev->dev_private;
2089+ uint32_t cmd = MI_FLUSH | MI_NO_WRITE_FLUSH;
2090+ uint32_t flush_domains = 0;
2091+ RING_LOCALS;
2092+
2093+ /* The sampler always gets flushed on i965 (sigh) */
2094+ if (IS_I965G(dev))
2095+ flush_domains |= I915_GEM_DOMAIN_SAMPLER;
2096+ BEGIN_LP_RING(2);
2097+ OUT_RING(cmd);
2098+ OUT_RING(0); /* noop */
2099+ ADVANCE_LP_RING();
2100+ return flush_domains;
2101+}
2102+
2103+/**
2104+ * Moves buffers associated only with the given active seqno from the active
2105+ * to inactive list, potentially freeing them.
2106+ */
2107+static void
2108+i915_gem_retire_request(struct drm_device *dev,
2109+ struct drm_i915_gem_request *request)
2110+{
2111+ drm_i915_private_t *dev_priv = dev->dev_private;
2112+
2113+ /* Move any buffers on the active list that are no longer referenced
2114+ * by the ringbuffer to the flushing/inactive lists as appropriate.
2115+ */
2116+ while (!list_empty(&dev_priv->mm.active_list)) {
2117+ struct drm_gem_object *obj;
2118+ struct drm_i915_gem_object *obj_priv;
2119+
2120+ obj_priv = list_first_entry(&dev_priv->mm.active_list,
2121+ struct drm_i915_gem_object,
2122+ list);
2123+ obj = obj_priv->obj;
2124+
2125+ /* If the seqno being retired doesn't match the oldest in the
2126+ * list, then the oldest in the list must still be newer than
2127+ * this seqno.
2128+ */
2129+ if (obj_priv->last_rendering_seqno != request->seqno)
2130+ return;
2131+#if WATCH_LRU
2132+ DRM_INFO("%s: retire %d moves to inactive list %p\n",
2133+ __func__, request->seqno, obj);
2134+#endif
2135+
2136+ if (obj->write_domain != 0) {
2137+ list_move_tail(&obj_priv->list,
2138+ &dev_priv->mm.flushing_list);
2139+ } else {
2140+ i915_gem_object_move_to_inactive(obj);
2141+ }
2142+ }
2143+
2144+ if (request->flush_domains != 0) {
2145+ struct drm_i915_gem_object *obj_priv, *next;
2146+
2147+ /* Clear the write domain and activity from any buffers
2148+ * that are just waiting for a flush matching the one retired.
2149+ */
2150+ list_for_each_entry_safe(obj_priv, next,
2151+ &dev_priv->mm.flushing_list, list) {
2152+ struct drm_gem_object *obj = obj_priv->obj;
2153+
2154+ if (obj->write_domain & request->flush_domains) {
2155+ obj->write_domain = 0;
2156+ i915_gem_object_move_to_inactive(obj);
2157+ }
2158+ }
2159+
2160+ }
2161+}
2162+
2163+/**
2164+ * Returns true if seq1 is later than seq2.
2165+ */
2166+static int
2167+i915_seqno_passed(uint32_t seq1, uint32_t seq2)
2168+{
2169+ return (int32_t)(seq1 - seq2) >= 0;
2170+}
2171+
2172+uint32_t
2173+i915_get_gem_seqno(struct drm_device *dev)
2174+{
2175+ drm_i915_private_t *dev_priv = dev->dev_private;
2176+
2177+ return READ_HWSP(dev_priv, I915_GEM_HWS_INDEX);
2178+}
2179+
2180+/**
2181+ * This function clears the request list as sequence numbers are passed.
2182+ */
2183+void
2184+i915_gem_retire_requests(struct drm_device *dev)
2185+{
2186+ drm_i915_private_t *dev_priv = dev->dev_private;
2187+ uint32_t seqno;
2188+
2189+ seqno = i915_get_gem_seqno(dev);
2190+
2191+ while (!list_empty(&dev_priv->mm.request_list)) {
2192+ struct drm_i915_gem_request *request;
2193+ uint32_t retiring_seqno;
2194+
2195+ request = list_first_entry(&dev_priv->mm.request_list,
2196+ struct drm_i915_gem_request,
2197+ list);
2198+ retiring_seqno = request->seqno;
2199+
2200+ if (i915_seqno_passed(seqno, retiring_seqno) ||
2201+ dev_priv->mm.wedged) {
2202+ i915_gem_retire_request(dev, request);
2203+
2204+ list_del(&request->list);
2205+ drm_free(request, sizeof(*request), DRM_MEM_DRIVER);
2206+ } else
2207+ break;
2208+ }
2209+}
2210+
2211+void
2212+i915_gem_retire_work_handler(struct work_struct *work)
2213+{
2214+ drm_i915_private_t *dev_priv;
2215+ struct drm_device *dev;
2216+
2217+ dev_priv = container_of(work, drm_i915_private_t,
2218+ mm.retire_work.work);
2219+ dev = dev_priv->dev;
2220+
2221+ mutex_lock(&dev->struct_mutex);
2222+ i915_gem_retire_requests(dev);
2223+ if (!list_empty(&dev_priv->mm.request_list))
2224+ schedule_delayed_work(&dev_priv->mm.retire_work, HZ);
2225+ mutex_unlock(&dev->struct_mutex);
2226+}
2227+
2228+/**
2229+ * Waits for a sequence number to be signaled, and cleans up the
2230+ * request and object lists appropriately for that event.
2231+ */
2232+int
2233+i915_wait_request(struct drm_device *dev, uint32_t seqno)
2234+{
2235+ drm_i915_private_t *dev_priv = dev->dev_private;
2236+ int ret = 0;
2237+
2238+ BUG_ON(seqno == 0);
2239+
2240+ if (!i915_seqno_passed(i915_get_gem_seqno(dev), seqno)) {
2241+ dev_priv->mm.waiting_gem_seqno = seqno;
2242+ i915_user_irq_get(dev);
2243+ ret = wait_event_interruptible(dev_priv->irq_queue,
2244+ i915_seqno_passed(i915_get_gem_seqno(dev),
2245+ seqno) ||
2246+ dev_priv->mm.wedged);
2247+ i915_user_irq_put(dev);
2248+ dev_priv->mm.waiting_gem_seqno = 0;
2249+ }
2250+ if (dev_priv->mm.wedged)
2251+ ret = -EIO;
2252+
2253+ if (ret && ret != -ERESTARTSYS)
2254+ DRM_ERROR("%s returns %d (awaiting %d at %d)\n",
2255+ __func__, ret, seqno, i915_get_gem_seqno(dev));
2256+
2257+ /* Directly dispatch request retiring. While we have the work queue
2258+ * to handle this, the waiter on a request often wants an associated
2259+ * buffer to have made it to the inactive list, and we would need
2260+ * a separate wait queue to handle that.
2261+ */
2262+ if (ret == 0)
2263+ i915_gem_retire_requests(dev);
2264+
2265+ return ret;
2266+}
2267+
2268+static void
2269+i915_gem_flush(struct drm_device *dev,
2270+ uint32_t invalidate_domains,
2271+ uint32_t flush_domains)
2272+{
2273+ drm_i915_private_t *dev_priv = dev->dev_private;
2274+ uint32_t cmd;
2275+ RING_LOCALS;
2276+
2277+#if WATCH_EXEC
2278+ DRM_INFO("%s: invalidate %08x flush %08x\n", __func__,
2279+ invalidate_domains, flush_domains);
2280+#endif
2281+
2282+ if (flush_domains & I915_GEM_DOMAIN_CPU)
2283+ drm_agp_chipset_flush(dev);
2284+
2285+ if ((invalidate_domains | flush_domains) & ~(I915_GEM_DOMAIN_CPU |
2286+ I915_GEM_DOMAIN_GTT)) {
2287+ /*
2288+ * read/write caches:
2289+ *
2290+ * I915_GEM_DOMAIN_RENDER is always invalidated, but is
2291+ * only flushed if MI_NO_WRITE_FLUSH is unset. On 965, it is
2292+ * also flushed at 2d versus 3d pipeline switches.
2293+ *
2294+ * read-only caches:
2295+ *
2296+ * I915_GEM_DOMAIN_SAMPLER is flushed on pre-965 if
2297+ * MI_READ_FLUSH is set, and is always flushed on 965.
2298+ *
2299+ * I915_GEM_DOMAIN_COMMAND may not exist?
2300+ *
2301+ * I915_GEM_DOMAIN_INSTRUCTION, which exists on 965, is
2302+ * invalidated when MI_EXE_FLUSH is set.
2303+ *
2304+ * I915_GEM_DOMAIN_VERTEX, which exists on 965, is
2305+ * invalidated with every MI_FLUSH.
2306+ *
2307+ * TLBs:
2308+ *
2309+ * On 965, TLBs associated with I915_GEM_DOMAIN_COMMAND
2310+ * and I915_GEM_DOMAIN_CPU in are invalidated at PTE write and
2311+ * I915_GEM_DOMAIN_RENDER and I915_GEM_DOMAIN_SAMPLER
2312+ * are flushed at any MI_FLUSH.
2313+ */
2314+
2315+ cmd = MI_FLUSH | MI_NO_WRITE_FLUSH;
2316+ if ((invalidate_domains|flush_domains) &
2317+ I915_GEM_DOMAIN_RENDER)
2318+ cmd &= ~MI_NO_WRITE_FLUSH;
2319+ if (!IS_I965G(dev)) {
2320+ /*
2321+ * On the 965, the sampler cache always gets flushed
2322+ * and this bit is reserved.
2323+ */
2324+ if (invalidate_domains & I915_GEM_DOMAIN_SAMPLER)
2325+ cmd |= MI_READ_FLUSH;
2326+ }
2327+ if (invalidate_domains & I915_GEM_DOMAIN_INSTRUCTION)
2328+ cmd |= MI_EXE_FLUSH;
2329+
2330+#if WATCH_EXEC
2331+ DRM_INFO("%s: queue flush %08x to ring\n", __func__, cmd);
2332+#endif
2333+ BEGIN_LP_RING(2);
2334+ OUT_RING(cmd);
2335+ OUT_RING(0); /* noop */
2336+ ADVANCE_LP_RING();
2337+ }
2338+}
2339+
2340+/**
2341+ * Ensures that all rendering to the object has completed and the object is
2342+ * safe to unbind from the GTT or access from the CPU.
2343+ */
2344+static int
2345+i915_gem_object_wait_rendering(struct drm_gem_object *obj)
2346+{
2347+ struct drm_device *dev = obj->dev;
2348+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
2349+ int ret;
2350+
2351+ /* If there are writes queued to the buffer, flush and
2352+ * create a new seqno to wait for.
2353+ */
2354+ if (obj->write_domain & ~(I915_GEM_DOMAIN_CPU|I915_GEM_DOMAIN_GTT)) {
2355+ uint32_t write_domain = obj->write_domain;
2356+#if WATCH_BUF
2357+ DRM_INFO("%s: flushing object %p from write domain %08x\n",
2358+ __func__, obj, write_domain);
2359+#endif
2360+ i915_gem_flush(dev, 0, write_domain);
2361+
2362+ i915_gem_object_move_to_active(obj);
2363+ obj_priv->last_rendering_seqno = i915_add_request(dev,
2364+ write_domain);
2365+ BUG_ON(obj_priv->last_rendering_seqno == 0);
2366+#if WATCH_LRU
2367+ DRM_INFO("%s: flush moves to exec list %p\n", __func__, obj);
2368+#endif
2369+ }
2370+
2371+ /* If there is rendering queued on the buffer being evicted, wait for
2372+ * it.
2373+ */
2374+ if (obj_priv->active) {
2375+#if WATCH_BUF
2376+ DRM_INFO("%s: object %p wait for seqno %08x\n",
2377+ __func__, obj, obj_priv->last_rendering_seqno);
2378+#endif
2379+ ret = i915_wait_request(dev, obj_priv->last_rendering_seqno);
2380+ if (ret != 0)
2381+ return ret;
2382+ }
2383+
2384+ return 0;
2385+}
2386+
2387+/**
2388+ * Unbinds an object from the GTT aperture.
2389+ */
2390+static int
2391+i915_gem_object_unbind(struct drm_gem_object *obj)
2392+{
2393+ struct drm_device *dev = obj->dev;
2394+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
2395+ int ret = 0;
2396+
2397+#if WATCH_BUF
2398+ DRM_INFO("%s:%d %p\n", __func__, __LINE__, obj);
2399+ DRM_INFO("gtt_space %p\n", obj_priv->gtt_space);
2400+#endif
2401+ if (obj_priv->gtt_space == NULL)
2402+ return 0;
2403+
2404+ if (obj_priv->pin_count != 0) {
2405+ DRM_ERROR("Attempting to unbind pinned buffer\n");
2406+ return -EINVAL;
2407+ }
2408+
2409+ /* Wait for any rendering to complete
2410+ */
2411+ ret = i915_gem_object_wait_rendering(obj);
2412+ if (ret) {
2413+ DRM_ERROR("wait_rendering failed: %d\n", ret);
2414+ return ret;
2415+ }
2416+
2417+ /* Move the object to the CPU domain to ensure that
2418+ * any possible CPU writes while it's not in the GTT
2419+ * are flushed when we go to remap it. This will
2420+ * also ensure that all pending GPU writes are finished
2421+ * before we unbind.
2422+ */
2423+ ret = i915_gem_object_set_domain(obj, I915_GEM_DOMAIN_CPU,
2424+ I915_GEM_DOMAIN_CPU);
2425+ if (ret) {
2426+ DRM_ERROR("set_domain failed: %d\n", ret);
2427+ return ret;
2428+ }
2429+
2430+ if (obj_priv->agp_mem != NULL) {
2431+ drm_unbind_agp(obj_priv->agp_mem);
2432+ drm_free_agp(obj_priv->agp_mem, obj->size / PAGE_SIZE);
2433+ obj_priv->agp_mem = NULL;
2434+ }
2435+
2436+ BUG_ON(obj_priv->active);
2437+
2438+ i915_gem_object_free_page_list(obj);
2439+
2440+ if (obj_priv->gtt_space) {
2441+ atomic_dec(&dev->gtt_count);
2442+ atomic_sub(obj->size, &dev->gtt_memory);
2443+
2444+ drm_mm_put_block(obj_priv->gtt_space);
2445+ obj_priv->gtt_space = NULL;
2446+ }
2447+
2448+ /* Remove ourselves from the LRU list if present. */
2449+ if (!list_empty(&obj_priv->list))
2450+ list_del_init(&obj_priv->list);
2451+
2452+ return 0;
2453+}
2454+
2455+static int
2456+i915_gem_evict_something(struct drm_device *dev)
2457+{
2458+ drm_i915_private_t *dev_priv = dev->dev_private;
2459+ struct drm_gem_object *obj;
2460+ struct drm_i915_gem_object *obj_priv;
2461+ int ret = 0;
2462+
2463+ for (;;) {
2464+ /* If there's an inactive buffer available now, grab it
2465+ * and be done.
2466+ */
2467+ if (!list_empty(&dev_priv->mm.inactive_list)) {
2468+ obj_priv = list_first_entry(&dev_priv->mm.inactive_list,
2469+ struct drm_i915_gem_object,
2470+ list);
2471+ obj = obj_priv->obj;
2472+ BUG_ON(obj_priv->pin_count != 0);
2473+#if WATCH_LRU
2474+ DRM_INFO("%s: evicting %p\n", __func__, obj);
2475+#endif
2476+ BUG_ON(obj_priv->active);
2477+
2478+ /* Wait on the rendering and unbind the buffer. */
2479+ ret = i915_gem_object_unbind(obj);
2480+ break;
2481+ }
2482+
2483+ /* If we didn't get anything, but the ring is still processing
2484+ * things, wait for one of those things to finish and hopefully
2485+ * leave us a buffer to evict.
2486+ */
2487+ if (!list_empty(&dev_priv->mm.request_list)) {
2488+ struct drm_i915_gem_request *request;
2489+
2490+ request = list_first_entry(&dev_priv->mm.request_list,
2491+ struct drm_i915_gem_request,
2492+ list);
2493+
2494+ ret = i915_wait_request(dev, request->seqno);
2495+ if (ret)
2496+ break;
2497+
2498+ /* if waiting caused an object to become inactive,
2499+ * then loop around and wait for it. Otherwise, we
2500+ * assume that waiting freed and unbound something,
2501+ * so there should now be some space in the GTT
2502+ */
2503+ if (!list_empty(&dev_priv->mm.inactive_list))
2504+ continue;
2505+ break;
2506+ }
2507+
2508+ /* If we didn't have anything on the request list but there
2509+ * are buffers awaiting a flush, emit one and try again.
2510+ * When we wait on it, those buffers waiting for that flush
2511+ * will get moved to inactive.
2512+ */
2513+ if (!list_empty(&dev_priv->mm.flushing_list)) {
2514+ obj_priv = list_first_entry(&dev_priv->mm.flushing_list,
2515+ struct drm_i915_gem_object,
2516+ list);
2517+ obj = obj_priv->obj;
2518+
2519+ i915_gem_flush(dev,
2520+ obj->write_domain,
2521+ obj->write_domain);
2522+ i915_add_request(dev, obj->write_domain);
2523+
2524+ obj = NULL;
2525+ continue;
2526+ }
2527+
2528+ DRM_ERROR("inactive empty %d request empty %d "
2529+ "flushing empty %d\n",
2530+ list_empty(&dev_priv->mm.inactive_list),
2531+ list_empty(&dev_priv->mm.request_list),
2532+ list_empty(&dev_priv->mm.flushing_list));
2533+ /* If we didn't do any of the above, there's nothing to be done
2534+ * and we just can't fit it in.
2535+ */
2536+ return -ENOMEM;
2537+ }
2538+ return ret;
2539+}
2540+
2541+static int
2542+i915_gem_object_get_page_list(struct drm_gem_object *obj)
2543+{
2544+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
2545+ int page_count, i;
2546+ struct address_space *mapping;
2547+ struct inode *inode;
2548+ struct page *page;
2549+ int ret;
2550+
2551+ if (obj_priv->page_list)
2552+ return 0;
2553+
2554+ /* Get the list of pages out of our struct file. They'll be pinned
2555+ * at this point until we release them.
2556+ */
2557+ page_count = obj->size / PAGE_SIZE;
2558+ BUG_ON(obj_priv->page_list != NULL);
2559+ obj_priv->page_list = drm_calloc(page_count, sizeof(struct page *),
2560+ DRM_MEM_DRIVER);
2561+ if (obj_priv->page_list == NULL) {
2562+ DRM_ERROR("Faled to allocate page list\n");
2563+ return -ENOMEM;
2564+ }
2565+
2566+ inode = obj->filp->f_path.dentry->d_inode;
2567+ mapping = inode->i_mapping;
2568+ for (i = 0; i < page_count; i++) {
2569+ page = read_mapping_page(mapping, i, NULL);
2570+ if (IS_ERR(page)) {
2571+ ret = PTR_ERR(page);
2572+ DRM_ERROR("read_mapping_page failed: %d\n", ret);
2573+ i915_gem_object_free_page_list(obj);
2574+ return ret;
2575+ }
2576+ obj_priv->page_list[i] = page;
2577+ }
2578+ return 0;
2579+}
2580+
2581+/**
2582+ * Finds free space in the GTT aperture and binds the object there.
2583+ */
2584+static int
2585+i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment)
2586+{
2587+ struct drm_device *dev = obj->dev;
2588+ drm_i915_private_t *dev_priv = dev->dev_private;
2589+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
2590+ struct drm_mm_node *free_space;
2591+ int page_count, ret;
2592+
2593+ if (alignment == 0)
2594+ alignment = PAGE_SIZE;
2595+ if (alignment & (PAGE_SIZE - 1)) {
2596+ DRM_ERROR("Invalid object alignment requested %u\n", alignment);
2597+ return -EINVAL;
2598+ }
2599+
2600+ search_free:
2601+ free_space = drm_mm_search_free(&dev_priv->mm.gtt_space,
2602+ obj->size, alignment, 0);
2603+ if (free_space != NULL) {
2604+ obj_priv->gtt_space = drm_mm_get_block(free_space, obj->size,
2605+ alignment);
2606+ if (obj_priv->gtt_space != NULL) {
2607+ obj_priv->gtt_space->private = obj;
2608+ obj_priv->gtt_offset = obj_priv->gtt_space->start;
2609+ }
2610+ }
2611+ if (obj_priv->gtt_space == NULL) {
2612+ /* If the gtt is empty and we're still having trouble
2613+ * fitting our object in, we're out of memory.
2614+ */
2615+#if WATCH_LRU
2616+ DRM_INFO("%s: GTT full, evicting something\n", __func__);
2617+#endif
2618+ if (list_empty(&dev_priv->mm.inactive_list) &&
2619+ list_empty(&dev_priv->mm.flushing_list) &&
2620+ list_empty(&dev_priv->mm.active_list)) {
2621+ DRM_ERROR("GTT full, but LRU list empty\n");
2622+ return -ENOMEM;
2623+ }
2624+
2625+ ret = i915_gem_evict_something(dev);
2626+ if (ret != 0) {
2627+ DRM_ERROR("Failed to evict a buffer %d\n", ret);
2628+ return ret;
2629+ }
2630+ goto search_free;
2631+ }
2632+
2633+#if WATCH_BUF
2634+ DRM_INFO("Binding object of size %d at 0x%08x\n",
2635+ obj->size, obj_priv->gtt_offset);
2636+#endif
2637+ ret = i915_gem_object_get_page_list(obj);
2638+ if (ret) {
2639+ drm_mm_put_block(obj_priv->gtt_space);
2640+ obj_priv->gtt_space = NULL;
2641+ return ret;
2642+ }
2643+
2644+ page_count = obj->size / PAGE_SIZE;
2645+ /* Create an AGP memory structure pointing at our pages, and bind it
2646+ * into the GTT.
2647+ */
2648+ obj_priv->agp_mem = drm_agp_bind_pages(dev,
2649+ obj_priv->page_list,
2650+ page_count,
2651+ obj_priv->gtt_offset);
2652+ if (obj_priv->agp_mem == NULL) {
2653+ i915_gem_object_free_page_list(obj);
2654+ drm_mm_put_block(obj_priv->gtt_space);
2655+ obj_priv->gtt_space = NULL;
2656+ return -ENOMEM;
2657+ }
2658+ atomic_inc(&dev->gtt_count);
2659+ atomic_add(obj->size, &dev->gtt_memory);
2660+
2661+ /* Assert that the object is not currently in any GPU domain. As it
2662+ * wasn't in the GTT, there shouldn't be any way it could have been in
2663+ * a GPU cache
2664+ */
2665+ BUG_ON(obj->read_domains & ~(I915_GEM_DOMAIN_CPU|I915_GEM_DOMAIN_GTT));
2666+ BUG_ON(obj->write_domain & ~(I915_GEM_DOMAIN_CPU|I915_GEM_DOMAIN_GTT));
2667+
2668+ return 0;
2669+}
2670+
2671+void
2672+i915_gem_clflush_object(struct drm_gem_object *obj)
2673+{
2674+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
2675+
2676+ /* If we don't have a page list set up, then we're not pinned
2677+ * to GPU, and we can ignore the cache flush because it'll happen
2678+ * again at bind time.
2679+ */
2680+ if (obj_priv->page_list == NULL)
2681+ return;
2682+
2683+ drm_clflush_pages(obj_priv->page_list, obj->size / PAGE_SIZE);
2684+}
2685+
2686+/*
2687+ * Set the next domain for the specified object. This
2688+ * may not actually perform the necessary flushing/invaliding though,
2689+ * as that may want to be batched with other set_domain operations
2690+ *
2691+ * This is (we hope) the only really tricky part of gem. The goal
2692+ * is fairly simple -- track which caches hold bits of the object
2693+ * and make sure they remain coherent. A few concrete examples may
2694+ * help to explain how it works. For shorthand, we use the notation
2695+ * (read_domains, write_domain), e.g. (CPU, CPU) to indicate the
2696+ * a pair of read and write domain masks.
2697+ *
2698+ * Case 1: the batch buffer
2699+ *
2700+ * 1. Allocated
2701+ * 2. Written by CPU
2702+ * 3. Mapped to GTT
2703+ * 4. Read by GPU
2704+ * 5. Unmapped from GTT
2705+ * 6. Freed
2706+ *
2707+ * Let's take these a step at a time
2708+ *
2709+ * 1. Allocated
2710+ * Pages allocated from the kernel may still have
2711+ * cache contents, so we set them to (CPU, CPU) always.
2712+ * 2. Written by CPU (using pwrite)
2713+ * The pwrite function calls set_domain (CPU, CPU) and
2714+ * this function does nothing (as nothing changes)
2715+ * 3. Mapped by GTT
2716+ * This function asserts that the object is not
2717+ * currently in any GPU-based read or write domains
2718+ * 4. Read by GPU
2719+ * i915_gem_execbuffer calls set_domain (COMMAND, 0).
2720+ * As write_domain is zero, this function adds in the
2721+ * current read domains (CPU+COMMAND, 0).
2722+ * flush_domains is set to CPU.
2723+ * invalidate_domains is set to COMMAND
2724+ * clflush is run to get data out of the CPU caches
2725+ * then i915_dev_set_domain calls i915_gem_flush to
2726+ * emit an MI_FLUSH and drm_agp_chipset_flush
2727+ * 5. Unmapped from GTT
2728+ * i915_gem_object_unbind calls set_domain (CPU, CPU)
2729+ * flush_domains and invalidate_domains end up both zero
2730+ * so no flushing/invalidating happens
2731+ * 6. Freed
2732+ * yay, done
2733+ *
2734+ * Case 2: The shared render buffer
2735+ *
2736+ * 1. Allocated
2737+ * 2. Mapped to GTT
2738+ * 3. Read/written by GPU
2739+ * 4. set_domain to (CPU,CPU)
2740+ * 5. Read/written by CPU
2741+ * 6. Read/written by GPU
2742+ *
2743+ * 1. Allocated
2744+ * Same as last example, (CPU, CPU)
2745+ * 2. Mapped to GTT
2746+ * Nothing changes (assertions find that it is not in the GPU)
2747+ * 3. Read/written by GPU
2748+ * execbuffer calls set_domain (RENDER, RENDER)
2749+ * flush_domains gets CPU
2750+ * invalidate_domains gets GPU
2751+ * clflush (obj)
2752+ * MI_FLUSH and drm_agp_chipset_flush
2753+ * 4. set_domain (CPU, CPU)
2754+ * flush_domains gets GPU
2755+ * invalidate_domains gets CPU
2756+ * wait_rendering (obj) to make sure all drawing is complete.
2757+ * This will include an MI_FLUSH to get the data from GPU
2758+ * to memory
2759+ * clflush (obj) to invalidate the CPU cache
2760+ * Another MI_FLUSH in i915_gem_flush (eliminate this somehow?)
2761+ * 5. Read/written by CPU
2762+ * cache lines are loaded and dirtied
2763+ * 6. Read written by GPU
2764+ * Same as last GPU access
2765+ *
2766+ * Case 3: The constant buffer
2767+ *
2768+ * 1. Allocated
2769+ * 2. Written by CPU
2770+ * 3. Read by GPU
2771+ * 4. Updated (written) by CPU again
2772+ * 5. Read by GPU
2773+ *
2774+ * 1. Allocated
2775+ * (CPU, CPU)
2776+ * 2. Written by CPU
2777+ * (CPU, CPU)
2778+ * 3. Read by GPU
2779+ * (CPU+RENDER, 0)
2780+ * flush_domains = CPU
2781+ * invalidate_domains = RENDER
2782+ * clflush (obj)
2783+ * MI_FLUSH
2784+ * drm_agp_chipset_flush
2785+ * 4. Updated (written) by CPU again
2786+ * (CPU, CPU)
2787+ * flush_domains = 0 (no previous write domain)
2788+ * invalidate_domains = 0 (no new read domains)
2789+ * 5. Read by GPU
2790+ * (CPU+RENDER, 0)
2791+ * flush_domains = CPU
2792+ * invalidate_domains = RENDER
2793+ * clflush (obj)
2794+ * MI_FLUSH
2795+ * drm_agp_chipset_flush
2796+ */
2797+static int
2798+i915_gem_object_set_domain(struct drm_gem_object *obj,
2799+ uint32_t read_domains,
2800+ uint32_t write_domain)
2801+{
2802+ struct drm_device *dev = obj->dev;
2803+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
2804+ uint32_t invalidate_domains = 0;
2805+ uint32_t flush_domains = 0;
2806+ int ret;
2807+
2808+#if WATCH_BUF
2809+ DRM_INFO("%s: object %p read %08x -> %08x write %08x -> %08x\n",
2810+ __func__, obj,
2811+ obj->read_domains, read_domains,
2812+ obj->write_domain, write_domain);
2813+#endif
2814+ /*
2815+ * If the object isn't moving to a new write domain,
2816+ * let the object stay in multiple read domains
2817+ */
2818+ if (write_domain == 0)
2819+ read_domains |= obj->read_domains;
2820+ else
2821+ obj_priv->dirty = 1;
2822+
2823+ /*
2824+ * Flush the current write domain if
2825+ * the new read domains don't match. Invalidate
2826+ * any read domains which differ from the old
2827+ * write domain
2828+ */
2829+ if (obj->write_domain && obj->write_domain != read_domains) {
2830+ flush_domains |= obj->write_domain;
2831+ invalidate_domains |= read_domains & ~obj->write_domain;
2832+ }
2833+ /*
2834+ * Invalidate any read caches which may have
2835+ * stale data. That is, any new read domains.
2836+ */
2837+ invalidate_domains |= read_domains & ~obj->read_domains;
2838+ if ((flush_domains | invalidate_domains) & I915_GEM_DOMAIN_CPU) {
2839+#if WATCH_BUF
2840+ DRM_INFO("%s: CPU domain flush %08x invalidate %08x\n",
2841+ __func__, flush_domains, invalidate_domains);
2842+#endif
2843+ /*
2844+ * If we're invaliding the CPU cache and flushing a GPU cache,
2845+ * then pause for rendering so that the GPU caches will be
2846+ * flushed before the cpu cache is invalidated
2847+ */
2848+ if ((invalidate_domains & I915_GEM_DOMAIN_CPU) &&
2849+ (flush_domains & ~(I915_GEM_DOMAIN_CPU |
2850+ I915_GEM_DOMAIN_GTT))) {
2851+ ret = i915_gem_object_wait_rendering(obj);
2852+ if (ret)
2853+ return ret;
2854+ }
2855+ i915_gem_clflush_object(obj);
2856+ }
2857+
2858+ if ((write_domain | flush_domains) != 0)
2859+ obj->write_domain = write_domain;
2860+
2861+ /* If we're invalidating the CPU domain, clear the per-page CPU
2862+ * domain list as well.
2863+ */
2864+ if (obj_priv->page_cpu_valid != NULL &&
2865+ (write_domain != 0 ||
2866+ read_domains & I915_GEM_DOMAIN_CPU)) {
2867+ drm_free(obj_priv->page_cpu_valid, obj->size / PAGE_SIZE,
2868+ DRM_MEM_DRIVER);
2869+ obj_priv->page_cpu_valid = NULL;
2870+ }
2871+ obj->read_domains = read_domains;
2872+
2873+ dev->invalidate_domains |= invalidate_domains;
2874+ dev->flush_domains |= flush_domains;
2875+#if WATCH_BUF
2876+ DRM_INFO("%s: read %08x write %08x invalidate %08x flush %08x\n",
2877+ __func__,
2878+ obj->read_domains, obj->write_domain,
2879+ dev->invalidate_domains, dev->flush_domains);
2880+#endif
2881+ return 0;
2882+}
2883+
2884+/**
2885+ * Set the read/write domain on a range of the object.
2886+ *
2887+ * Currently only implemented for CPU reads, otherwise drops to normal
2888+ * i915_gem_object_set_domain().
2889+ */
2890+static int
2891+i915_gem_object_set_domain_range(struct drm_gem_object *obj,
2892+ uint64_t offset,
2893+ uint64_t size,
2894+ uint32_t read_domains,
2895+ uint32_t write_domain)
2896+{
2897+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
2898+ int ret, i;
2899+
2900+ if (obj->read_domains & I915_GEM_DOMAIN_CPU)
2901+ return 0;
2902+
2903+ if (read_domains != I915_GEM_DOMAIN_CPU ||
2904+ write_domain != 0)
2905+ return i915_gem_object_set_domain(obj,
2906+ read_domains, write_domain);
2907+
2908+ /* Wait on any GPU rendering to the object to be flushed. */
2909+ if (obj->write_domain & ~(I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT)) {
2910+ ret = i915_gem_object_wait_rendering(obj);
2911+ if (ret)
2912+ return ret;
2913+ }
2914+
2915+ if (obj_priv->page_cpu_valid == NULL) {
2916+ obj_priv->page_cpu_valid = drm_calloc(1, obj->size / PAGE_SIZE,
2917+ DRM_MEM_DRIVER);
2918+ }
2919+
2920+ /* Flush the cache on any pages that are still invalid from the CPU's
2921+ * perspective.
2922+ */
2923+ for (i = offset / PAGE_SIZE; i <= (offset + size - 1) / PAGE_SIZE; i++) {
2924+ if (obj_priv->page_cpu_valid[i])
2925+ continue;
2926+
2927+ drm_clflush_pages(obj_priv->page_list + i, 1);
2928+
2929+ obj_priv->page_cpu_valid[i] = 1;
2930+ }
2931+
2932+ return 0;
2933+}
2934+
2935+/**
2936+ * Once all of the objects have been set in the proper domain,
2937+ * perform the necessary flush and invalidate operations.
2938+ *
2939+ * Returns the write domains flushed, for use in flush tracking.
2940+ */
2941+static uint32_t
2942+i915_gem_dev_set_domain(struct drm_device *dev)
2943+{
2944+ uint32_t flush_domains = dev->flush_domains;
2945+
2946+ /*
2947+ * Now that all the buffers are synced to the proper domains,
2948+ * flush and invalidate the collected domains
2949+ */
2950+ if (dev->invalidate_domains | dev->flush_domains) {
2951+#if WATCH_EXEC
2952+ DRM_INFO("%s: invalidate_domains %08x flush_domains %08x\n",
2953+ __func__,
2954+ dev->invalidate_domains,
2955+ dev->flush_domains);
2956+#endif
2957+ i915_gem_flush(dev,
2958+ dev->invalidate_domains,
2959+ dev->flush_domains);
2960+ dev->invalidate_domains = 0;
2961+ dev->flush_domains = 0;
2962+ }
2963+
2964+ return flush_domains;
2965+}
2966+
2967+/**
2968+ * Pin an object to the GTT and evaluate the relocations landing in it.
2969+ */
2970+static int
2971+i915_gem_object_pin_and_relocate(struct drm_gem_object *obj,
2972+ struct drm_file *file_priv,
2973+ struct drm_i915_gem_exec_object *entry)
2974+{
2975+ struct drm_device *dev = obj->dev;
2976+ struct drm_i915_gem_relocation_entry reloc;
2977+ struct drm_i915_gem_relocation_entry __user *relocs;
2978+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
2979+ int i, ret;
2980+ uint32_t last_reloc_offset = -1;
2981+ void *reloc_page = NULL;
2982+
2983+ /* Choose the GTT offset for our buffer and put it there. */
2984+ ret = i915_gem_object_pin(obj, (uint32_t) entry->alignment);
2985+ if (ret)
2986+ return ret;
2987+
2988+ entry->offset = obj_priv->gtt_offset;
2989+
2990+ relocs = (struct drm_i915_gem_relocation_entry __user *)
2991+ (uintptr_t) entry->relocs_ptr;
2992+ /* Apply the relocations, using the GTT aperture to avoid cache
2993+ * flushing requirements.
2994+ */
2995+ for (i = 0; i < entry->relocation_count; i++) {
2996+ struct drm_gem_object *target_obj;
2997+ struct drm_i915_gem_object *target_obj_priv;
2998+ uint32_t reloc_val, reloc_offset, *reloc_entry;
2999+ int ret;
3000+
3001+ ret = copy_from_user(&reloc, relocs + i, sizeof(reloc));
3002+ if (ret != 0) {
3003+ i915_gem_object_unpin(obj);
3004+ return ret;
3005+ }
3006+
3007+ target_obj = drm_gem_object_lookup(obj->dev, file_priv,
3008+ reloc.target_handle);
3009+ if (target_obj == NULL) {
3010+ i915_gem_object_unpin(obj);
3011+ return -EBADF;
3012+ }
3013+ target_obj_priv = target_obj->driver_private;
3014+
3015+ /* The target buffer should have appeared before us in the
3016+ * exec_object list, so it should have a GTT space bound by now.
3017+ */
3018+ if (target_obj_priv->gtt_space == NULL) {
3019+ DRM_ERROR("No GTT space found for object %d\n",
3020+ reloc.target_handle);
3021+ drm_gem_object_unreference(target_obj);
3022+ i915_gem_object_unpin(obj);
3023+ return -EINVAL;
3024+ }
3025+
3026+ if (reloc.offset > obj->size - 4) {
3027+ DRM_ERROR("Relocation beyond object bounds: "
3028+ "obj %p target %d offset %d size %d.\n",
3029+ obj, reloc.target_handle,
3030+ (int) reloc.offset, (int) obj->size);
3031+ drm_gem_object_unreference(target_obj);
3032+ i915_gem_object_unpin(obj);
3033+ return -EINVAL;
3034+ }
3035+ if (reloc.offset & 3) {
3036+ DRM_ERROR("Relocation not 4-byte aligned: "
3037+ "obj %p target %d offset %d.\n",
3038+ obj, reloc.target_handle,
3039+ (int) reloc.offset);
3040+ drm_gem_object_unreference(target_obj);
3041+ i915_gem_object_unpin(obj);
3042+ return -EINVAL;
3043+ }
3044+
3045+ if (reloc.write_domain && target_obj->pending_write_domain &&
3046+ reloc.write_domain != target_obj->pending_write_domain) {
3047+ DRM_ERROR("Write domain conflict: "
3048+ "obj %p target %d offset %d "
3049+ "new %08x old %08x\n",
3050+ obj, reloc.target_handle,
3051+ (int) reloc.offset,
3052+ reloc.write_domain,
3053+ target_obj->pending_write_domain);
3054+ drm_gem_object_unreference(target_obj);
3055+ i915_gem_object_unpin(obj);
3056+ return -EINVAL;
3057+ }
3058+
3059+#if WATCH_RELOC
3060+ DRM_INFO("%s: obj %p offset %08x target %d "
3061+ "read %08x write %08x gtt %08x "
3062+ "presumed %08x delta %08x\n",
3063+ __func__,
3064+ obj,
3065+ (int) reloc.offset,
3066+ (int) reloc.target_handle,
3067+ (int) reloc.read_domains,
3068+ (int) reloc.write_domain,
3069+ (int) target_obj_priv->gtt_offset,
3070+ (int) reloc.presumed_offset,
3071+ reloc.delta);
3072+#endif
3073+
3074+ target_obj->pending_read_domains |= reloc.read_domains;
3075+ target_obj->pending_write_domain |= reloc.write_domain;
3076+
3077+ /* If the relocation already has the right value in it, no
3078+ * more work needs to be done.
3079+ */
3080+ if (target_obj_priv->gtt_offset == reloc.presumed_offset) {
3081+ drm_gem_object_unreference(target_obj);
3082+ continue;
3083+ }
3084+
3085+ /* Now that we're going to actually write some data in,
3086+ * make sure that any rendering using this buffer's contents
3087+ * is completed.
3088+ */
3089+ i915_gem_object_wait_rendering(obj);
3090+
3091+ /* As we're writing through the gtt, flush
3092+ * any CPU writes before we write the relocations
3093+ */
3094+ if (obj->write_domain & I915_GEM_DOMAIN_CPU) {
3095+ i915_gem_clflush_object(obj);
3096+ drm_agp_chipset_flush(dev);
3097+ obj->write_domain = 0;
3098+ }
3099+
3100+ /* Map the page containing the relocation we're going to
3101+ * perform.
3102+ */
3103+ reloc_offset = obj_priv->gtt_offset + reloc.offset;
3104+ if (reloc_page == NULL ||
3105+ (last_reloc_offset & ~(PAGE_SIZE - 1)) !=
3106+ (reloc_offset & ~(PAGE_SIZE - 1))) {
3107+ if (reloc_page != NULL)
3108+ iounmap(reloc_page);
3109+
3110+ reloc_page = ioremap(dev->agp->base +
3111+ (reloc_offset & ~(PAGE_SIZE - 1)),
3112+ PAGE_SIZE);
3113+ last_reloc_offset = reloc_offset;
3114+ if (reloc_page == NULL) {
3115+ drm_gem_object_unreference(target_obj);
3116+ i915_gem_object_unpin(obj);
3117+ return -ENOMEM;
3118+ }
3119+ }
3120+
3121+ reloc_entry = (uint32_t *)((char *)reloc_page +
3122+ (reloc_offset & (PAGE_SIZE - 1)));
3123+ reloc_val = target_obj_priv->gtt_offset + reloc.delta;
3124+
3125+#if WATCH_BUF
3126+ DRM_INFO("Applied relocation: %p@0x%08x %08x -> %08x\n",
3127+ obj, (unsigned int) reloc.offset,
3128+ readl(reloc_entry), reloc_val);
3129+#endif
3130+ writel(reloc_val, reloc_entry);
3131+
3132+ /* Write the updated presumed offset for this entry back out
3133+ * to the user.
3134+ */
3135+ reloc.presumed_offset = target_obj_priv->gtt_offset;
3136+ ret = copy_to_user(relocs + i, &reloc, sizeof(reloc));
3137+ if (ret != 0) {
3138+ drm_gem_object_unreference(target_obj);
3139+ i915_gem_object_unpin(obj);
3140+ return ret;
3141+ }
3142+
3143+ drm_gem_object_unreference(target_obj);
3144+ }
3145+
3146+ if (reloc_page != NULL)
3147+ iounmap(reloc_page);
3148+
3149+#if WATCH_BUF
3150+ if (0)
3151+ i915_gem_dump_object(obj, 128, __func__, ~0);
3152+#endif
3153+ return 0;
3154+}
3155+
3156+/** Dispatch a batchbuffer to the ring
3157+ */
3158+static int
3159+i915_dispatch_gem_execbuffer(struct drm_device *dev,
3160+ struct drm_i915_gem_execbuffer *exec,
3161+ uint64_t exec_offset)
3162+{
3163+ drm_i915_private_t *dev_priv = dev->dev_private;
3164+ struct drm_clip_rect __user *boxes = (struct drm_clip_rect __user *)
3165+ (uintptr_t) exec->cliprects_ptr;
3166+ int nbox = exec->num_cliprects;
3167+ int i = 0, count;
3168+ uint32_t exec_start, exec_len;
3169+ RING_LOCALS;
3170+
3171+ exec_start = (uint32_t) exec_offset + exec->batch_start_offset;
3172+ exec_len = (uint32_t) exec->batch_len;
3173+
3174+ if ((exec_start | exec_len) & 0x7) {
3175+ DRM_ERROR("alignment\n");
3176+ return -EINVAL;
3177+ }
3178+
3179+ if (!exec_start)
3180+ return -EINVAL;
3181+
3182+ count = nbox ? nbox : 1;
3183+
3184+ for (i = 0; i < count; i++) {
3185+ if (i < nbox) {
3186+ int ret = i915_emit_box(dev, boxes, i,
3187+ exec->DR1, exec->DR4);
3188+ if (ret)
3189+ return ret;
3190+ }
3191+
3192+ if (IS_I830(dev) || IS_845G(dev)) {
3193+ BEGIN_LP_RING(4);
3194+ OUT_RING(MI_BATCH_BUFFER);
3195+ OUT_RING(exec_start | MI_BATCH_NON_SECURE);
3196+ OUT_RING(exec_start + exec_len - 4);
3197+ OUT_RING(0);
3198+ ADVANCE_LP_RING();
3199+ } else {
3200+ BEGIN_LP_RING(2);
3201+ if (IS_I965G(dev)) {
3202+ OUT_RING(MI_BATCH_BUFFER_START |
3203+ (2 << 6) |
3204+ MI_BATCH_NON_SECURE_I965);
3205+ OUT_RING(exec_start);
3206+ } else {
3207+ OUT_RING(MI_BATCH_BUFFER_START |
3208+ (2 << 6));
3209+ OUT_RING(exec_start | MI_BATCH_NON_SECURE);
3210+ }
3211+ ADVANCE_LP_RING();
3212+ }
3213+ }
3214+
3215+ /* XXX breadcrumb */
3216+ return 0;
3217+}
3218+
3219+/* Throttle our rendering by waiting until the ring has completed our requests
3220+ * emitted over 20 msec ago.
3221+ *
3222+ * This should get us reasonable parallelism between CPU and GPU but also
3223+ * relatively low latency when blocking on a particular request to finish.
3224+ */
3225+static int
3226+i915_gem_ring_throttle(struct drm_device *dev, struct drm_file *file_priv)
3227+{
3228+ struct drm_i915_file_private *i915_file_priv = file_priv->driver_priv;
3229+ int ret = 0;
3230+ uint32_t seqno;
3231+
3232+ mutex_lock(&dev->struct_mutex);
3233+ seqno = i915_file_priv->mm.last_gem_throttle_seqno;
3234+ i915_file_priv->mm.last_gem_throttle_seqno =
3235+ i915_file_priv->mm.last_gem_seqno;
3236+ if (seqno)
3237+ ret = i915_wait_request(dev, seqno);
3238+ mutex_unlock(&dev->struct_mutex);
3239+ return ret;
3240+}
3241+
3242+int
3243+i915_gem_execbuffer(struct drm_device *dev, void *data,
3244+ struct drm_file *file_priv)
3245+{
3246+ drm_i915_private_t *dev_priv = dev->dev_private;
3247+ struct drm_i915_file_private *i915_file_priv = file_priv->driver_priv;
3248+ struct drm_i915_gem_execbuffer *args = data;
3249+ struct drm_i915_gem_exec_object *exec_list = NULL;
3250+ struct drm_gem_object **object_list = NULL;
3251+ struct drm_gem_object *batch_obj;
3252+ int ret, i, pinned = 0;
3253+ uint64_t exec_offset;
3254+ uint32_t seqno, flush_domains;
3255+
3256+#if WATCH_EXEC
3257+ DRM_INFO("buffers_ptr %d buffer_count %d len %08x\n",
3258+ (int) args->buffers_ptr, args->buffer_count, args->batch_len);
3259+#endif
3260+
3261+ /* Copy in the exec list from userland */
3262+ exec_list = drm_calloc(sizeof(*exec_list), args->buffer_count,
3263+ DRM_MEM_DRIVER);
3264+ object_list = drm_calloc(sizeof(*object_list), args->buffer_count,
3265+ DRM_MEM_DRIVER);
3266+ if (exec_list == NULL || object_list == NULL) {
3267+ DRM_ERROR("Failed to allocate exec or object list "
3268+ "for %d buffers\n",
3269+ args->buffer_count);
3270+ ret = -ENOMEM;
3271+ goto pre_mutex_err;
3272+ }
3273+ ret = copy_from_user(exec_list,
3274+ (struct drm_i915_relocation_entry __user *)
3275+ (uintptr_t) args->buffers_ptr,
3276+ sizeof(*exec_list) * args->buffer_count);
3277+ if (ret != 0) {
3278+ DRM_ERROR("copy %d exec entries failed %d\n",
3279+ args->buffer_count, ret);
3280+ goto pre_mutex_err;
3281+ }
3282+
3283+ mutex_lock(&dev->struct_mutex);
3284+
3285+ i915_verify_inactive(dev, __FILE__, __LINE__);
3286+
3287+ if (dev_priv->mm.wedged) {
3288+ DRM_ERROR("Execbuf while wedged\n");
3289+ mutex_unlock(&dev->struct_mutex);
3290+ return -EIO;
3291+ }
3292+
3293+ if (dev_priv->mm.suspended) {
3294+ DRM_ERROR("Execbuf while VT-switched.\n");
3295+ mutex_unlock(&dev->struct_mutex);
3296+ return -EBUSY;
3297+ }
3298+
3299+ /* Zero the gloabl flush/invalidate flags. These
3300+ * will be modified as each object is bound to the
3301+ * gtt
3302+ */
3303+ dev->invalidate_domains = 0;
3304+ dev->flush_domains = 0;
3305+
3306+ /* Look up object handles and perform the relocations */
3307+ for (i = 0; i < args->buffer_count; i++) {
3308+ object_list[i] = drm_gem_object_lookup(dev, file_priv,
3309+ exec_list[i].handle);
3310+ if (object_list[i] == NULL) {
3311+ DRM_ERROR("Invalid object handle %d at index %d\n",
3312+ exec_list[i].handle, i);
3313+ ret = -EBADF;
3314+ goto err;
3315+ }
3316+
3317+ object_list[i]->pending_read_domains = 0;
3318+ object_list[i]->pending_write_domain = 0;
3319+ ret = i915_gem_object_pin_and_relocate(object_list[i],
3320+ file_priv,
3321+ &exec_list[i]);
3322+ if (ret) {
3323+ DRM_ERROR("object bind and relocate failed %d\n", ret);
3324+ goto err;
3325+ }
3326+ pinned = i + 1;
3327+ }
3328+
3329+ /* Set the pending read domains for the batch buffer to COMMAND */
3330+ batch_obj = object_list[args->buffer_count-1];
3331+ batch_obj->pending_read_domains = I915_GEM_DOMAIN_COMMAND;
3332+ batch_obj->pending_write_domain = 0;
3333+
3334+ i915_verify_inactive(dev, __FILE__, __LINE__);
3335+
3336+ for (i = 0; i < args->buffer_count; i++) {
3337+ struct drm_gem_object *obj = object_list[i];
3338+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
3339+
3340+ if (obj_priv->gtt_space == NULL) {
3341+ /* We evicted the buffer in the process of validating
3342+ * our set of buffers in. We could try to recover by
3343+ * kicking them everything out and trying again from
3344+ * the start.
3345+ */
3346+ ret = -ENOMEM;
3347+ goto err;
3348+ }
3349+
3350+ /* make sure all previous memory operations have passed */
3351+ ret = i915_gem_object_set_domain(obj,
3352+ obj->pending_read_domains,
3353+ obj->pending_write_domain);
3354+ if (ret)
3355+ goto err;
3356+ }
3357+
3358+ i915_verify_inactive(dev, __FILE__, __LINE__);
3359+
3360+ /* Flush/invalidate caches and chipset buffer */
3361+ flush_domains = i915_gem_dev_set_domain(dev);
3362+
3363+ i915_verify_inactive(dev, __FILE__, __LINE__);
3364+
3365+#if WATCH_COHERENCY
3366+ for (i = 0; i < args->buffer_count; i++) {
3367+ i915_gem_object_check_coherency(object_list[i],
3368+ exec_list[i].handle);
3369+ }
3370+#endif
3371+
3372+ exec_offset = exec_list[args->buffer_count - 1].offset;
3373+
3374+#if WATCH_EXEC
3375+ i915_gem_dump_object(object_list[args->buffer_count - 1],
3376+ args->batch_len,
3377+ __func__,
3378+ ~0);
3379+#endif
3380+
3381+ (void)i915_add_request(dev, flush_domains);
3382+
3383+ /* Exec the batchbuffer */
3384+ ret = i915_dispatch_gem_execbuffer(dev, args, exec_offset);
3385+ if (ret) {
3386+ DRM_ERROR("dispatch failed %d\n", ret);
3387+ goto err;
3388+ }
3389+
3390+ /*
3391+ * Ensure that the commands in the batch buffer are
3392+ * finished before the interrupt fires
3393+ */
3394+ flush_domains = i915_retire_commands(dev);
3395+
3396+ i915_verify_inactive(dev, __FILE__, __LINE__);
3397+
3398+ /*
3399+ * Get a seqno representing the execution of the current buffer,
3400+ * which we can wait on. We would like to mitigate these interrupts,
3401+ * likely by only creating seqnos occasionally (so that we have
3402+ * *some* interrupts representing completion of buffers that we can
3403+ * wait on when trying to clear up gtt space).
3404+ */
3405+ seqno = i915_add_request(dev, flush_domains);
3406+ BUG_ON(seqno == 0);
3407+ i915_file_priv->mm.last_gem_seqno = seqno;
3408+ for (i = 0; i < args->buffer_count; i++) {
3409+ struct drm_gem_object *obj = object_list[i];
3410+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
3411+
3412+ i915_gem_object_move_to_active(obj);
3413+ obj_priv->last_rendering_seqno = seqno;
3414+#if WATCH_LRU
3415+ DRM_INFO("%s: move to exec list %p\n", __func__, obj);
3416+#endif
3417+ }
3418+#if WATCH_LRU
3419+ i915_dump_lru(dev, __func__);
3420+#endif
3421+
3422+ i915_verify_inactive(dev, __FILE__, __LINE__);
3423+
3424+ /* Copy the new buffer offsets back to the user's exec list. */
3425+ ret = copy_to_user((struct drm_i915_relocation_entry __user *)
3426+ (uintptr_t) args->buffers_ptr,
3427+ exec_list,
3428+ sizeof(*exec_list) * args->buffer_count);
3429+ if (ret)
3430+ DRM_ERROR("failed to copy %d exec entries "
3431+ "back to user (%d)\n",
3432+ args->buffer_count, ret);
3433+err:
3434+ if (object_list != NULL) {
3435+ for (i = 0; i < pinned; i++)
3436+ i915_gem_object_unpin(object_list[i]);
3437+
3438+ for (i = 0; i < args->buffer_count; i++)
3439+ drm_gem_object_unreference(object_list[i]);
3440+ }
3441+ mutex_unlock(&dev->struct_mutex);
3442+
3443+pre_mutex_err:
3444+ drm_free(object_list, sizeof(*object_list) * args->buffer_count,
3445+ DRM_MEM_DRIVER);
3446+ drm_free(exec_list, sizeof(*exec_list) * args->buffer_count,
3447+ DRM_MEM_DRIVER);
3448+
3449+ return ret;
3450+}
3451+
3452+int
3453+i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment)
3454+{
3455+ struct drm_device *dev = obj->dev;
3456+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
3457+ int ret;
3458+
3459+ i915_verify_inactive(dev, __FILE__, __LINE__);
3460+ if (obj_priv->gtt_space == NULL) {
3461+ ret = i915_gem_object_bind_to_gtt(obj, alignment);
3462+ if (ret != 0) {
3463+ DRM_ERROR("Failure to bind: %d", ret);
3464+ return ret;
3465+ }
3466+ }
3467+ obj_priv->pin_count++;
3468+
3469+ /* If the object is not active and not pending a flush,
3470+ * remove it from the inactive list
3471+ */
3472+ if (obj_priv->pin_count == 1) {
3473+ atomic_inc(&dev->pin_count);
3474+ atomic_add(obj->size, &dev->pin_memory);
3475+ if (!obj_priv->active &&
3476+ (obj->write_domain & ~(I915_GEM_DOMAIN_CPU |
3477+ I915_GEM_DOMAIN_GTT)) == 0 &&
3478+ !list_empty(&obj_priv->list))
3479+ list_del_init(&obj_priv->list);
3480+ }
3481+ i915_verify_inactive(dev, __FILE__, __LINE__);
3482+
3483+ return 0;
3484+}
3485+
3486+void
3487+i915_gem_object_unpin(struct drm_gem_object *obj)
3488+{
3489+ struct drm_device *dev = obj->dev;
3490+ drm_i915_private_t *dev_priv = dev->dev_private;
3491+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
3492+
3493+ i915_verify_inactive(dev, __FILE__, __LINE__);
3494+ obj_priv->pin_count--;
3495+ BUG_ON(obj_priv->pin_count < 0);
3496+ BUG_ON(obj_priv->gtt_space == NULL);
3497+
3498+ /* If the object is no longer pinned, and is
3499+ * neither active nor being flushed, then stick it on
3500+ * the inactive list
3501+ */
3502+ if (obj_priv->pin_count == 0) {
3503+ if (!obj_priv->active &&
3504+ (obj->write_domain & ~(I915_GEM_DOMAIN_CPU |
3505+ I915_GEM_DOMAIN_GTT)) == 0)
3506+ list_move_tail(&obj_priv->list,
3507+ &dev_priv->mm.inactive_list);
3508+ atomic_dec(&dev->pin_count);
3509+ atomic_sub(obj->size, &dev->pin_memory);
3510+ }
3511+ i915_verify_inactive(dev, __FILE__, __LINE__);
3512+}
3513+
3514+int
3515+i915_gem_pin_ioctl(struct drm_device *dev, void *data,
3516+ struct drm_file *file_priv)
3517+{
3518+ struct drm_i915_gem_pin *args = data;
3519+ struct drm_gem_object *obj;
3520+ struct drm_i915_gem_object *obj_priv;
3521+ int ret;
3522+
3523+ mutex_lock(&dev->struct_mutex);
3524+
3525+ obj = drm_gem_object_lookup(dev, file_priv, args->handle);
3526+ if (obj == NULL) {
3527+ DRM_ERROR("Bad handle in i915_gem_pin_ioctl(): %d\n",
3528+ args->handle);
3529+ mutex_unlock(&dev->struct_mutex);
3530+ return -EBADF;
3531+ }
3532+ obj_priv = obj->driver_private;
3533+
3534+ ret = i915_gem_object_pin(obj, args->alignment);
3535+ if (ret != 0) {
3536+ drm_gem_object_unreference(obj);
3537+ mutex_unlock(&dev->struct_mutex);
3538+ return ret;
3539+ }
3540+
3541+ /* XXX - flush the CPU caches for pinned objects
3542+ * as the X server doesn't manage domains yet
3543+ */
3544+ if (obj->write_domain & I915_GEM_DOMAIN_CPU) {
3545+ i915_gem_clflush_object(obj);
3546+ drm_agp_chipset_flush(dev);
3547+ obj->write_domain = 0;
3548+ }
3549+ args->offset = obj_priv->gtt_offset;
3550+ drm_gem_object_unreference(obj);
3551+ mutex_unlock(&dev->struct_mutex);
3552+
3553+ return 0;
3554+}
3555+
3556+int
3557+i915_gem_unpin_ioctl(struct drm_device *dev, void *data,
3558+ struct drm_file *file_priv)
3559+{
3560+ struct drm_i915_gem_pin *args = data;
3561+ struct drm_gem_object *obj;
3562+
3563+ mutex_lock(&dev->struct_mutex);
3564+
3565+ obj = drm_gem_object_lookup(dev, file_priv, args->handle);
3566+ if (obj == NULL) {
3567+ DRM_ERROR("Bad handle in i915_gem_unpin_ioctl(): %d\n",
3568+ args->handle);
3569+ mutex_unlock(&dev->struct_mutex);
3570+ return -EBADF;
3571+ }
3572+
3573+ i915_gem_object_unpin(obj);
3574+
3575+ drm_gem_object_unreference(obj);
3576+ mutex_unlock(&dev->struct_mutex);
3577+ return 0;
3578+}
3579+
3580+int
3581+i915_gem_busy_ioctl(struct drm_device *dev, void *data,
3582+ struct drm_file *file_priv)
3583+{
3584+ struct drm_i915_gem_busy *args = data;
3585+ struct drm_gem_object *obj;
3586+ struct drm_i915_gem_object *obj_priv;
3587+
3588+ mutex_lock(&dev->struct_mutex);
3589+ obj = drm_gem_object_lookup(dev, file_priv, args->handle);
3590+ if (obj == NULL) {
3591+ DRM_ERROR("Bad handle in i915_gem_busy_ioctl(): %d\n",
3592+ args->handle);
3593+ mutex_unlock(&dev->struct_mutex);
3594+ return -EBADF;
3595+ }
3596+
3597+ obj_priv = obj->driver_private;
3598+ args->busy = obj_priv->active;
3599+
3600+ drm_gem_object_unreference(obj);
3601+ mutex_unlock(&dev->struct_mutex);
3602+ return 0;
3603+}
3604+
3605+int
3606+i915_gem_throttle_ioctl(struct drm_device *dev, void *data,
3607+ struct drm_file *file_priv)
3608+{
3609+ return i915_gem_ring_throttle(dev, file_priv);
3610+}
3611+
3612+int i915_gem_init_object(struct drm_gem_object *obj)
3613+{
3614+ struct drm_i915_gem_object *obj_priv;
3615+
3616+ obj_priv = drm_calloc(1, sizeof(*obj_priv), DRM_MEM_DRIVER);
3617+ if (obj_priv == NULL)
3618+ return -ENOMEM;
3619+
3620+ /*
3621+ * We've just allocated pages from the kernel,
3622+ * so they've just been written by the CPU with
3623+ * zeros. They'll need to be clflushed before we
3624+ * use them with the GPU.
3625+ */
3626+ obj->write_domain = I915_GEM_DOMAIN_CPU;
3627+ obj->read_domains = I915_GEM_DOMAIN_CPU;
3628+
3629+ obj->driver_private = obj_priv;
3630+ obj_priv->obj = obj;
3631+ INIT_LIST_HEAD(&obj_priv->list);
3632+ return 0;
3633+}
3634+
3635+void i915_gem_free_object(struct drm_gem_object *obj)
3636+{
3637+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
3638+
3639+ while (obj_priv->pin_count > 0)
3640+ i915_gem_object_unpin(obj);
3641+
3642+ i915_gem_object_unbind(obj);
3643+
3644+ drm_free(obj_priv->page_cpu_valid, 1, DRM_MEM_DRIVER);
3645+ drm_free(obj->driver_private, 1, DRM_MEM_DRIVER);
3646+}
3647+
3648+static int
3649+i915_gem_set_domain(struct drm_gem_object *obj,
3650+ struct drm_file *file_priv,
3651+ uint32_t read_domains,
3652+ uint32_t write_domain)
3653+{
3654+ struct drm_device *dev = obj->dev;
3655+ int ret;
3656+ uint32_t flush_domains;
3657+
3658+ BUG_ON(!mutex_is_locked(&dev->struct_mutex));
3659+
3660+ ret = i915_gem_object_set_domain(obj, read_domains, write_domain);
3661+ if (ret)
3662+ return ret;
3663+ flush_domains = i915_gem_dev_set_domain(obj->dev);
3664+
3665+ if (flush_domains & ~(I915_GEM_DOMAIN_CPU|I915_GEM_DOMAIN_GTT))
3666+ (void) i915_add_request(dev, flush_domains);
3667+
3668+ return 0;
3669+}
3670+
3671+/** Unbinds all objects that are on the given buffer list. */
3672+static int
3673+i915_gem_evict_from_list(struct drm_device *dev, struct list_head *head)
3674+{
3675+ struct drm_gem_object *obj;
3676+ struct drm_i915_gem_object *obj_priv;
3677+ int ret;
3678+
3679+ while (!list_empty(head)) {
3680+ obj_priv = list_first_entry(head,
3681+ struct drm_i915_gem_object,
3682+ list);
3683+ obj = obj_priv->obj;
3684+
3685+ if (obj_priv->pin_count != 0) {
3686+ DRM_ERROR("Pinned object in unbind list\n");
3687+ mutex_unlock(&dev->struct_mutex);
3688+ return -EINVAL;
3689+ }
3690+
3691+ ret = i915_gem_object_unbind(obj);
3692+ if (ret != 0) {
3693+ DRM_ERROR("Error unbinding object in LeaveVT: %d\n",
3694+ ret);
3695+ mutex_unlock(&dev->struct_mutex);
3696+ return ret;
3697+ }
3698+ }
3699+
3700+
3701+ return 0;
3702+}
3703+
3704+static int
3705+i915_gem_idle(struct drm_device *dev)
3706+{
3707+ drm_i915_private_t *dev_priv = dev->dev_private;
3708+ uint32_t seqno, cur_seqno, last_seqno;
3709+ int stuck, ret;
3710+
3711+ if (dev_priv->mm.suspended)
3712+ return 0;
3713+
3714+ /* Hack! Don't let anybody do execbuf while we don't control the chip.
3715+ * We need to replace this with a semaphore, or something.
3716+ */
3717+ dev_priv->mm.suspended = 1;
3718+
3719+ i915_kernel_lost_context(dev);
3720+
3721+ /* Flush the GPU along with all non-CPU write domains
3722+ */
3723+ i915_gem_flush(dev, ~(I915_GEM_DOMAIN_CPU|I915_GEM_DOMAIN_GTT),
3724+ ~(I915_GEM_DOMAIN_CPU|I915_GEM_DOMAIN_GTT));
3725+ seqno = i915_add_request(dev, ~(I915_GEM_DOMAIN_CPU |
3726+ I915_GEM_DOMAIN_GTT));
3727+
3728+ if (seqno == 0) {
3729+ mutex_unlock(&dev->struct_mutex);
3730+ return -ENOMEM;
3731+ }
3732+
3733+ dev_priv->mm.waiting_gem_seqno = seqno;
3734+ last_seqno = 0;
3735+ stuck = 0;
3736+ for (;;) {
3737+ cur_seqno = i915_get_gem_seqno(dev);
3738+ if (i915_seqno_passed(cur_seqno, seqno))
3739+ break;
3740+ if (last_seqno == cur_seqno) {
3741+ if (stuck++ > 100) {
3742+ DRM_ERROR("hardware wedged\n");
3743+ dev_priv->mm.wedged = 1;
3744+ DRM_WAKEUP(&dev_priv->irq_queue);
3745+ break;
3746+ }
3747+ }
3748+ msleep(10);
3749+ last_seqno = cur_seqno;
3750+ }
3751+ dev_priv->mm.waiting_gem_seqno = 0;
3752+
3753+ i915_gem_retire_requests(dev);
3754+
3755+ /* Active and flushing should now be empty as we've
3756+ * waited for a sequence higher than any pending execbuffer
3757+ */
3758+ BUG_ON(!list_empty(&dev_priv->mm.active_list));
3759+ BUG_ON(!list_empty(&dev_priv->mm.flushing_list));
3760+
3761+ /* Request should now be empty as we've also waited
3762+ * for the last request in the list
3763+ */
3764+ BUG_ON(!list_empty(&dev_priv->mm.request_list));
3765+
3766+ /* Move all buffers out of the GTT. */
3767+ ret = i915_gem_evict_from_list(dev, &dev_priv->mm.inactive_list);
3768+ if (ret)
3769+ return ret;
3770+
3771+ BUG_ON(!list_empty(&dev_priv->mm.active_list));
3772+ BUG_ON(!list_empty(&dev_priv->mm.flushing_list));
3773+ BUG_ON(!list_empty(&dev_priv->mm.inactive_list));
3774+ BUG_ON(!list_empty(&dev_priv->mm.request_list));
3775+ return 0;
3776+}
3777+
3778+static int
3779+i915_gem_init_hws(struct drm_device *dev)
3780+{
3781+ drm_i915_private_t *dev_priv = dev->dev_private;
3782+ struct drm_gem_object *obj;
3783+ struct drm_i915_gem_object *obj_priv;
3784+ int ret;
3785+
3786+ /* If we need a physical address for the status page, it's already
3787+ * initialized at driver load time.
3788+ */
3789+ if (!I915_NEED_GFX_HWS(dev))
3790+ return 0;
3791+
3792+ obj = drm_gem_object_alloc(dev, 4096);
3793+ if (obj == NULL) {
3794+ DRM_ERROR("Failed to allocate status page\n");
3795+ return -ENOMEM;
3796+ }
3797+ obj_priv = obj->driver_private;
3798+
3799+ ret = i915_gem_object_pin(obj, 4096);
3800+ if (ret != 0) {
3801+ drm_gem_object_unreference(obj);
3802+ return ret;
3803+ }
3804+
3805+ dev_priv->status_gfx_addr = obj_priv->gtt_offset;
3806+ dev_priv->hws_map.offset = dev->agp->base + obj_priv->gtt_offset;
3807+ dev_priv->hws_map.size = 4096;
3808+ dev_priv->hws_map.type = 0;
3809+ dev_priv->hws_map.flags = 0;
3810+ dev_priv->hws_map.mtrr = 0;
3811+
3812+ drm_core_ioremap(&dev_priv->hws_map, dev);
3813+ if (dev_priv->hws_map.handle == NULL) {
3814+ DRM_ERROR("Failed to map status page.\n");
3815+ memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map));
3816+ drm_gem_object_unreference(obj);
3817+ return -EINVAL;
3818+ }
3819+ dev_priv->hws_obj = obj;
3820+ dev_priv->hw_status_page = dev_priv->hws_map.handle;
3821+ memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
3822+ I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr);
3823+ DRM_DEBUG("hws offset: 0x%08x\n", dev_priv->status_gfx_addr);
3824+
3825+ return 0;
3826+}
3827+
3828+static int
3829+i915_gem_init_ringbuffer(struct drm_device *dev)
3830+{
3831+ drm_i915_private_t *dev_priv = dev->dev_private;
3832+ struct drm_gem_object *obj;
3833+ struct drm_i915_gem_object *obj_priv;
3834+ int ret;
3835+
3836+ ret = i915_gem_init_hws(dev);
3837+ if (ret != 0)
3838+ return ret;
3839+
3840+ obj = drm_gem_object_alloc(dev, 128 * 1024);
3841+ if (obj == NULL) {
3842+ DRM_ERROR("Failed to allocate ringbuffer\n");
3843+ return -ENOMEM;
3844+ }
3845+ obj_priv = obj->driver_private;
3846+
3847+ ret = i915_gem_object_pin(obj, 4096);
3848+ if (ret != 0) {
3849+ drm_gem_object_unreference(obj);
3850+ return ret;
3851+ }
3852+
3853+ /* Set up the kernel mapping for the ring. */
3854+ dev_priv->ring.Size = obj->size;
3855+ dev_priv->ring.tail_mask = obj->size - 1;
3856+
3857+ dev_priv->ring.map.offset = dev->agp->base + obj_priv->gtt_offset;
3858+ dev_priv->ring.map.size = obj->size;
3859+ dev_priv->ring.map.type = 0;
3860+ dev_priv->ring.map.flags = 0;
3861+ dev_priv->ring.map.mtrr = 0;
3862+
3863+ drm_core_ioremap(&dev_priv->ring.map, dev);
3864+ if (dev_priv->ring.map.handle == NULL) {
3865+ DRM_ERROR("Failed to map ringbuffer.\n");
3866+ memset(&dev_priv->ring, 0, sizeof(dev_priv->ring));
3867+ drm_gem_object_unreference(obj);
3868+ return -EINVAL;
3869+ }
3870+ dev_priv->ring.ring_obj = obj;
3871+ dev_priv->ring.virtual_start = dev_priv->ring.map.handle;
3872+
3873+ /* Stop the ring if it's running. */
3874+ I915_WRITE(PRB0_CTL, 0);
3875+ I915_WRITE(PRB0_HEAD, 0);
3876+ I915_WRITE(PRB0_TAIL, 0);
3877+ I915_WRITE(PRB0_START, 0);
3878+
3879+ /* Initialize the ring. */
3880+ I915_WRITE(PRB0_START, obj_priv->gtt_offset);
3881+ I915_WRITE(PRB0_CTL,
3882+ ((obj->size - 4096) & RING_NR_PAGES) |
3883+ RING_NO_REPORT |
3884+ RING_VALID);
3885+
3886+ /* Update our cache of the ring state */
3887+ i915_kernel_lost_context(dev);
3888+
3889+ return 0;
3890+}
3891+
3892+static void
3893+i915_gem_cleanup_ringbuffer(struct drm_device *dev)
3894+{
3895+ drm_i915_private_t *dev_priv = dev->dev_private;
3896+
3897+ if (dev_priv->ring.ring_obj == NULL)
3898+ return;
3899+
3900+ drm_core_ioremapfree(&dev_priv->ring.map, dev);
3901+
3902+ i915_gem_object_unpin(dev_priv->ring.ring_obj);
3903+ drm_gem_object_unreference(dev_priv->ring.ring_obj);
3904+ dev_priv->ring.ring_obj = NULL;
3905+ memset(&dev_priv->ring, 0, sizeof(dev_priv->ring));
3906+
3907+ if (dev_priv->hws_obj != NULL) {
3908+ i915_gem_object_unpin(dev_priv->hws_obj);
3909+ drm_gem_object_unreference(dev_priv->hws_obj);
3910+ dev_priv->hws_obj = NULL;
3911+ memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map));
3912+
3913+ /* Write high address into HWS_PGA when disabling. */
3914+ I915_WRITE(HWS_PGA, 0x1ffff000);
3915+ }
3916+}
3917+
3918+int
3919+i915_gem_entervt_ioctl(struct drm_device *dev, void *data,
3920+ struct drm_file *file_priv)
3921+{
3922+ drm_i915_private_t *dev_priv = dev->dev_private;
3923+ int ret;
3924+
3925+ if (dev_priv->mm.wedged) {
3926+ DRM_ERROR("Reenabling wedged hardware, good luck\n");
3927+ dev_priv->mm.wedged = 0;
3928+ }
3929+
3930+ ret = i915_gem_init_ringbuffer(dev);
3931+ if (ret != 0)
3932+ return ret;
3933+
3934+ mutex_lock(&dev->struct_mutex);
3935+ BUG_ON(!list_empty(&dev_priv->mm.active_list));
3936+ BUG_ON(!list_empty(&dev_priv->mm.flushing_list));
3937+ BUG_ON(!list_empty(&dev_priv->mm.inactive_list));
3938+ BUG_ON(!list_empty(&dev_priv->mm.request_list));
3939+ dev_priv->mm.suspended = 0;
3940+ mutex_unlock(&dev->struct_mutex);
3941+ return 0;
3942+}
3943+
3944+int
3945+i915_gem_leavevt_ioctl(struct drm_device *dev, void *data,
3946+ struct drm_file *file_priv)
3947+{
3948+ int ret;
3949+
3950+ mutex_lock(&dev->struct_mutex);
3951+ ret = i915_gem_idle(dev);
3952+ if (ret == 0)
3953+ i915_gem_cleanup_ringbuffer(dev);
3954+ mutex_unlock(&dev->struct_mutex);
3955+
3956+ return 0;
3957+}
3958+
3959+void
3960+i915_gem_lastclose(struct drm_device *dev)
3961+{
3962+ int ret;
3963+ drm_i915_private_t *dev_priv = dev->dev_private;
3964+
3965+ mutex_lock(&dev->struct_mutex);
3966+
3967+ if (dev_priv->ring.ring_obj != NULL) {
3968+ ret = i915_gem_idle(dev);
3969+ if (ret)
3970+ DRM_ERROR("failed to idle hardware: %d\n", ret);
3971+
3972+ i915_gem_cleanup_ringbuffer(dev);
3973+ }
3974+
3975+ mutex_unlock(&dev->struct_mutex);
3976+}
3977+
3978+void
3979+i915_gem_load(struct drm_device *dev)
3980+{
3981+ drm_i915_private_t *dev_priv = dev->dev_private;
3982+
3983+ INIT_LIST_HEAD(&dev_priv->mm.active_list);
3984+ INIT_LIST_HEAD(&dev_priv->mm.flushing_list);
3985+ INIT_LIST_HEAD(&dev_priv->mm.inactive_list);
3986+ INIT_LIST_HEAD(&dev_priv->mm.request_list);
3987+ INIT_DELAYED_WORK(&dev_priv->mm.retire_work,
3988+ i915_gem_retire_work_handler);
3989+ dev_priv->mm.next_gem_seqno = 1;
3990+
3991+ i915_gem_detect_bit_6_swizzle(dev);
3992+}
3993diff --git a/drivers/gpu/drm/i915/i915_gem_debug.c b/drivers/gpu/drm/i915/i915_gem_debug.c
3994new file mode 100644
3995index 0000000..131c088
3996--- /dev/null
3997+++ b/drivers/gpu/drm/i915/i915_gem_debug.c
3998@@ -0,0 +1,201 @@
3999+/*
4000+ * Copyright © 2008 Intel Corporation
4001+ *
4002+ * Permission is hereby granted, free of charge, to any person obtaining a
4003+ * copy of this software and associated documentation files (the "Software"),
4004+ * to deal in the Software without restriction, including without limitation
4005+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
4006+ * and/or sell copies of the Software, and to permit persons to whom the
4007+ * Software is furnished to do so, subject to the following conditions:
4008+ *
4009+ * The above copyright notice and this permission notice (including the next
4010+ * paragraph) shall be included in all copies or substantial portions of the
4011+ * Software.
4012+ *
4013+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
4014+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
4015+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
4016+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
4017+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
4018+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
4019+ * IN THE SOFTWARE.
4020+ *
4021+ * Authors:
4022+ * Keith Packard <keithp@keithp.com>
4023+ *
4024+ */
4025+
4026+#include "drmP.h"
4027+#include "drm.h"
4028+#include "i915_drm.h"
4029+#include "i915_drv.h"
4030+
4031+#if WATCH_INACTIVE
4032+void
4033+i915_verify_inactive(struct drm_device *dev, char *file, int line)
4034+{
4035+ drm_i915_private_t *dev_priv = dev->dev_private;
4036+ struct drm_gem_object *obj;
4037+ struct drm_i915_gem_object *obj_priv;
4038+
4039+ list_for_each_entry(obj_priv, &dev_priv->mm.inactive_list, list) {
4040+ obj = obj_priv->obj;
4041+ if (obj_priv->pin_count || obj_priv->active ||
4042+ (obj->write_domain & ~(I915_GEM_DOMAIN_CPU |
4043+ I915_GEM_DOMAIN_GTT)))
4044+ DRM_ERROR("inactive %p (p %d a %d w %x) %s:%d\n",
4045+ obj,
4046+ obj_priv->pin_count, obj_priv->active,
4047+ obj->write_domain, file, line);
4048+ }
4049+}
4050+#endif /* WATCH_INACTIVE */
4051+
4052+
4053+#if WATCH_BUF | WATCH_EXEC | WATCH_PWRITE
4054+static void
4055+i915_gem_dump_page(struct page *page, uint32_t start, uint32_t end,
4056+ uint32_t bias, uint32_t mark)
4057+{
4058+ uint32_t *mem = kmap_atomic(page, KM_USER0);
4059+ int i;
4060+ for (i = start; i < end; i += 4)
4061+ DRM_INFO("%08x: %08x%s\n",
4062+ (int) (bias + i), mem[i / 4],
4063+ (bias + i == mark) ? " ********" : "");
4064+ kunmap_atomic(mem, KM_USER0);
4065+ /* give syslog time to catch up */
4066+ msleep(1);
4067+}
4068+
4069+void
4070+i915_gem_dump_object(struct drm_gem_object *obj, int len,
4071+ const char *where, uint32_t mark)
4072+{
4073+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
4074+ int page;
4075+
4076+ DRM_INFO("%s: object at offset %08x\n", where, obj_priv->gtt_offset);
4077+ for (page = 0; page < (len + PAGE_SIZE-1) / PAGE_SIZE; page++) {
4078+ int page_len, chunk, chunk_len;
4079+
4080+ page_len = len - page * PAGE_SIZE;
4081+ if (page_len > PAGE_SIZE)
4082+ page_len = PAGE_SIZE;
4083+
4084+ for (chunk = 0; chunk < page_len; chunk += 128) {
4085+ chunk_len = page_len - chunk;
4086+ if (chunk_len > 128)
4087+ chunk_len = 128;
4088+ i915_gem_dump_page(obj_priv->page_list[page],
4089+ chunk, chunk + chunk_len,
4090+ obj_priv->gtt_offset +
4091+ page * PAGE_SIZE,
4092+ mark);
4093+ }
4094+ }
4095+}
4096+#endif
4097+
4098+#if WATCH_LRU
4099+void
4100+i915_dump_lru(struct drm_device *dev, const char *where)
4101+{
4102+ drm_i915_private_t *dev_priv = dev->dev_private;
4103+ struct drm_i915_gem_object *obj_priv;
4104+
4105+ DRM_INFO("active list %s {\n", where);
4106+ list_for_each_entry(obj_priv, &dev_priv->mm.active_list,
4107+ list)
4108+ {
4109+ DRM_INFO(" %p: %08x\n", obj_priv,
4110+ obj_priv->last_rendering_seqno);
4111+ }
4112+ DRM_INFO("}\n");
4113+ DRM_INFO("flushing list %s {\n", where);
4114+ list_for_each_entry(obj_priv, &dev_priv->mm.flushing_list,
4115+ list)
4116+ {
4117+ DRM_INFO(" %p: %08x\n", obj_priv,
4118+ obj_priv->last_rendering_seqno);
4119+ }
4120+ DRM_INFO("}\n");
4121+ DRM_INFO("inactive %s {\n", where);
4122+ list_for_each_entry(obj_priv, &dev_priv->mm.inactive_list, list) {
4123+ DRM_INFO(" %p: %08x\n", obj_priv,
4124+ obj_priv->last_rendering_seqno);
4125+ }
4126+ DRM_INFO("}\n");
4127+}
4128+#endif
4129+
4130+
4131+#if WATCH_COHERENCY
4132+void
4133+i915_gem_object_check_coherency(struct drm_gem_object *obj, int handle)
4134+{
4135+ struct drm_device *dev = obj->dev;
4136+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
4137+ int page;
4138+ uint32_t *gtt_mapping;
4139+ uint32_t *backing_map = NULL;
4140+ int bad_count = 0;
4141+
4142+ DRM_INFO("%s: checking coherency of object %p@0x%08x (%d, %dkb):\n",
4143+ __func__, obj, obj_priv->gtt_offset, handle,
4144+ obj->size / 1024);
4145+
4146+ gtt_mapping = ioremap(dev->agp->base + obj_priv->gtt_offset,
4147+ obj->size);
4148+ if (gtt_mapping == NULL) {
4149+ DRM_ERROR("failed to map GTT space\n");
4150+ return;
4151+ }
4152+
4153+ for (page = 0; page < obj->size / PAGE_SIZE; page++) {
4154+ int i;
4155+
4156+ backing_map = kmap_atomic(obj_priv->page_list[page], KM_USER0);
4157+
4158+ if (backing_map == NULL) {
4159+ DRM_ERROR("failed to map backing page\n");
4160+ goto out;
4161+ }
4162+
4163+ for (i = 0; i < PAGE_SIZE / 4; i++) {
4164+ uint32_t cpuval = backing_map[i];
4165+ uint32_t gttval = readl(gtt_mapping +
4166+ page * 1024 + i);
4167+
4168+ if (cpuval != gttval) {
4169+ DRM_INFO("incoherent CPU vs GPU at 0x%08x: "
4170+ "0x%08x vs 0x%08x\n",
4171+ (int)(obj_priv->gtt_offset +
4172+ page * PAGE_SIZE + i * 4),
4173+ cpuval, gttval);
4174+ if (bad_count++ >= 8) {
4175+ DRM_INFO("...\n");
4176+ goto out;
4177+ }
4178+ }
4179+ }
4180+ kunmap_atomic(backing_map, KM_USER0);
4181+ backing_map = NULL;
4182+ }
4183+
4184+ out:
4185+ if (backing_map != NULL)
4186+ kunmap_atomic(backing_map, KM_USER0);
4187+ iounmap(gtt_mapping);
4188+
4189+ /* give syslog time to catch up */
4190+ msleep(1);
4191+
4192+ /* Directly flush the object, since we just loaded values with the CPU
4193+ * from the backing pages and we don't want to disturb the cache
4194+ * management that we're trying to observe.
4195+ */
4196+
4197+ i915_gem_clflush_object(obj);
4198+}
4199+#endif
4200diff --git a/drivers/gpu/drm/i915/i915_gem_proc.c b/drivers/gpu/drm/i915/i915_gem_proc.c
4201new file mode 100644
4202index 0000000..15d4160
4203--- /dev/null
4204+++ b/drivers/gpu/drm/i915/i915_gem_proc.c
4205@@ -0,0 +1,292 @@
4206+/*
4207+ * Copyright © 2008 Intel Corporation
4208+ *
4209+ * Permission is hereby granted, free of charge, to any person obtaining a
4210+ * copy of this software and associated documentation files (the "Software"),
4211+ * to deal in the Software without restriction, including without limitation
4212+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
4213+ * and/or sell copies of the Software, and to permit persons to whom the
4214+ * Software is furnished to do so, subject to the following conditions:
4215+ *
4216+ * The above copyright notice and this permission notice (including the next
4217+ * paragraph) shall be included in all copies or substantial portions of the
4218+ * Software.
4219+ *
4220+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
4221+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
4222+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
4223+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
4224+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
4225+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
4226+ * IN THE SOFTWARE.
4227+ *
4228+ * Authors:
4229+ * Eric Anholt <eric@anholt.net>
4230+ * Keith Packard <keithp@keithp.com>
4231+ *
4232+ */
4233+
4234+#include "drmP.h"
4235+#include "drm.h"
4236+#include "i915_drm.h"
4237+#include "i915_drv.h"
4238+
4239+static int i915_gem_active_info(char *buf, char **start, off_t offset,
4240+ int request, int *eof, void *data)
4241+{
4242+ struct drm_minor *minor = (struct drm_minor *) data;
4243+ struct drm_device *dev = minor->dev;
4244+ drm_i915_private_t *dev_priv = dev->dev_private;
4245+ struct drm_i915_gem_object *obj_priv;
4246+ int len = 0;
4247+
4248+ if (offset > DRM_PROC_LIMIT) {
4249+ *eof = 1;
4250+ return 0;
4251+ }
4252+
4253+ *start = &buf[offset];
4254+ *eof = 0;
4255+ DRM_PROC_PRINT("Active:\n");
4256+ list_for_each_entry(obj_priv, &dev_priv->mm.active_list,
4257+ list)
4258+ {
4259+ struct drm_gem_object *obj = obj_priv->obj;
4260+ if (obj->name) {
4261+ DRM_PROC_PRINT(" %p(%d): %08x %08x %d\n",
4262+ obj, obj->name,
4263+ obj->read_domains, obj->write_domain,
4264+ obj_priv->last_rendering_seqno);
4265+ } else {
4266+ DRM_PROC_PRINT(" %p: %08x %08x %d\n",
4267+ obj,
4268+ obj->read_domains, obj->write_domain,
4269+ obj_priv->last_rendering_seqno);
4270+ }
4271+ }
4272+ if (len > request + offset)
4273+ return request;
4274+ *eof = 1;
4275+ return len - offset;
4276+}
4277+
4278+static int i915_gem_flushing_info(char *buf, char **start, off_t offset,
4279+ int request, int *eof, void *data)
4280+{
4281+ struct drm_minor *minor = (struct drm_minor *) data;
4282+ struct drm_device *dev = minor->dev;
4283+ drm_i915_private_t *dev_priv = dev->dev_private;
4284+ struct drm_i915_gem_object *obj_priv;
4285+ int len = 0;
4286+
4287+ if (offset > DRM_PROC_LIMIT) {
4288+ *eof = 1;
4289+ return 0;
4290+ }
4291+
4292+ *start = &buf[offset];
4293+ *eof = 0;
4294+ DRM_PROC_PRINT("Flushing:\n");
4295+ list_for_each_entry(obj_priv, &dev_priv->mm.flushing_list,
4296+ list)
4297+ {
4298+ struct drm_gem_object *obj = obj_priv->obj;
4299+ if (obj->name) {
4300+ DRM_PROC_PRINT(" %p(%d): %08x %08x %d\n",
4301+ obj, obj->name,
4302+ obj->read_domains, obj->write_domain,
4303+ obj_priv->last_rendering_seqno);
4304+ } else {
4305+ DRM_PROC_PRINT(" %p: %08x %08x %d\n", obj,
4306+ obj->read_domains, obj->write_domain,
4307+ obj_priv->last_rendering_seqno);
4308+ }
4309+ }
4310+ if (len > request + offset)
4311+ return request;
4312+ *eof = 1;
4313+ return len - offset;
4314+}
4315+
4316+static int i915_gem_inactive_info(char *buf, char **start, off_t offset,
4317+ int request, int *eof, void *data)
4318+{
4319+ struct drm_minor *minor = (struct drm_minor *) data;
4320+ struct drm_device *dev = minor->dev;
4321+ drm_i915_private_t *dev_priv = dev->dev_private;
4322+ struct drm_i915_gem_object *obj_priv;
4323+ int len = 0;
4324+
4325+ if (offset > DRM_PROC_LIMIT) {
4326+ *eof = 1;
4327+ return 0;
4328+ }
4329+
4330+ *start = &buf[offset];
4331+ *eof = 0;
4332+ DRM_PROC_PRINT("Inactive:\n");
4333+ list_for_each_entry(obj_priv, &dev_priv->mm.inactive_list,
4334+ list)
4335+ {
4336+ struct drm_gem_object *obj = obj_priv->obj;
4337+ if (obj->name) {
4338+ DRM_PROC_PRINT(" %p(%d): %08x %08x %d\n",
4339+ obj, obj->name,
4340+ obj->read_domains, obj->write_domain,
4341+ obj_priv->last_rendering_seqno);
4342+ } else {
4343+ DRM_PROC_PRINT(" %p: %08x %08x %d\n", obj,
4344+ obj->read_domains, obj->write_domain,
4345+ obj_priv->last_rendering_seqno);
4346+ }
4347+ }
4348+ if (len > request + offset)
4349+ return request;
4350+ *eof = 1;
4351+ return len - offset;
4352+}
4353+
4354+static int i915_gem_request_info(char *buf, char **start, off_t offset,
4355+ int request, int *eof, void *data)
4356+{
4357+ struct drm_minor *minor = (struct drm_minor *) data;
4358+ struct drm_device *dev = minor->dev;
4359+ drm_i915_private_t *dev_priv = dev->dev_private;
4360+ struct drm_i915_gem_request *gem_request;
4361+ int len = 0;
4362+
4363+ if (offset > DRM_PROC_LIMIT) {
4364+ *eof = 1;
4365+ return 0;
4366+ }
4367+
4368+ *start = &buf[offset];
4369+ *eof = 0;
4370+ DRM_PROC_PRINT("Request:\n");
4371+ list_for_each_entry(gem_request, &dev_priv->mm.request_list,
4372+ list)
4373+ {
4374+ DRM_PROC_PRINT(" %d @ %d %08x\n",
4375+ gem_request->seqno,
4376+ (int) (jiffies - gem_request->emitted_jiffies),
4377+ gem_request->flush_domains);
4378+ }
4379+ if (len > request + offset)
4380+ return request;
4381+ *eof = 1;
4382+ return len - offset;
4383+}
4384+
4385+static int i915_gem_seqno_info(char *buf, char **start, off_t offset,
4386+ int request, int *eof, void *data)
4387+{
4388+ struct drm_minor *minor = (struct drm_minor *) data;
4389+ struct drm_device *dev = minor->dev;
4390+ drm_i915_private_t *dev_priv = dev->dev_private;
4391+ int len = 0;
4392+
4393+ if (offset > DRM_PROC_LIMIT) {
4394+ *eof = 1;
4395+ return 0;
4396+ }
4397+
4398+ *start = &buf[offset];
4399+ *eof = 0;
4400+ DRM_PROC_PRINT("Current sequence: %d\n", i915_get_gem_seqno(dev));
4401+ DRM_PROC_PRINT("Waiter sequence: %d\n",
4402+ dev_priv->mm.waiting_gem_seqno);
4403+ DRM_PROC_PRINT("IRQ sequence: %d\n", dev_priv->mm.irq_gem_seqno);
4404+ if (len > request + offset)
4405+ return request;
4406+ *eof = 1;
4407+ return len - offset;
4408+}
4409+
4410+
4411+static int i915_interrupt_info(char *buf, char **start, off_t offset,
4412+ int request, int *eof, void *data)
4413+{
4414+ struct drm_minor *minor = (struct drm_minor *) data;
4415+ struct drm_device *dev = minor->dev;
4416+ drm_i915_private_t *dev_priv = dev->dev_private;
4417+ int len = 0;
4418+
4419+ if (offset > DRM_PROC_LIMIT) {
4420+ *eof = 1;
4421+ return 0;
4422+ }
4423+
4424+ *start = &buf[offset];
4425+ *eof = 0;
4426+ DRM_PROC_PRINT("Interrupt enable: %08x\n",
4427+ I915_READ(IER));
4428+ DRM_PROC_PRINT("Interrupt identity: %08x\n",
4429+ I915_READ(IIR));
4430+ DRM_PROC_PRINT("Interrupt mask: %08x\n",
4431+ I915_READ(IMR));
4432+ DRM_PROC_PRINT("Pipe A stat: %08x\n",
4433+ I915_READ(PIPEASTAT));
4434+ DRM_PROC_PRINT("Pipe B stat: %08x\n",
4435+ I915_READ(PIPEBSTAT));
4436+ DRM_PROC_PRINT("Interrupts received: %d\n",
4437+ atomic_read(&dev_priv->irq_received));
4438+ DRM_PROC_PRINT("Current sequence: %d\n",
4439+ i915_get_gem_seqno(dev));
4440+ DRM_PROC_PRINT("Waiter sequence: %d\n",
4441+ dev_priv->mm.waiting_gem_seqno);
4442+ DRM_PROC_PRINT("IRQ sequence: %d\n",
4443+ dev_priv->mm.irq_gem_seqno);
4444+ if (len > request + offset)
4445+ return request;
4446+ *eof = 1;
4447+ return len - offset;
4448+}
4449+
4450+static struct drm_proc_list {
4451+ /** file name */
4452+ const char *name;
4453+ /** proc callback*/
4454+ int (*f) (char *, char **, off_t, int, int *, void *);
4455+} i915_gem_proc_list[] = {
4456+ {"i915_gem_active", i915_gem_active_info},
4457+ {"i915_gem_flushing", i915_gem_flushing_info},
4458+ {"i915_gem_inactive", i915_gem_inactive_info},
4459+ {"i915_gem_request", i915_gem_request_info},
4460+ {"i915_gem_seqno", i915_gem_seqno_info},
4461+ {"i915_gem_interrupt", i915_interrupt_info},
4462+};
4463+
4464+#define I915_GEM_PROC_ENTRIES ARRAY_SIZE(i915_gem_proc_list)
4465+
4466+int i915_gem_proc_init(struct drm_minor *minor)
4467+{
4468+ struct proc_dir_entry *ent;
4469+ int i, j;
4470+
4471+ for (i = 0; i < I915_GEM_PROC_ENTRIES; i++) {
4472+ ent = create_proc_entry(i915_gem_proc_list[i].name,
4473+ S_IFREG | S_IRUGO, minor->dev_root);
4474+ if (!ent) {
4475+ DRM_ERROR("Cannot create /proc/dri/.../%s\n",
4476+ i915_gem_proc_list[i].name);
4477+ for (j = 0; j < i; j++)
4478+ remove_proc_entry(i915_gem_proc_list[i].name,
4479+ minor->dev_root);
4480+ return -1;
4481+ }
4482+ ent->read_proc = i915_gem_proc_list[i].f;
4483+ ent->data = minor;
4484+ }
4485+ return 0;
4486+}
4487+
4488+void i915_gem_proc_cleanup(struct drm_minor *minor)
4489+{
4490+ int i;
4491+
4492+ if (!minor->dev_root)
4493+ return;
4494+
4495+ for (i = 0; i < I915_GEM_PROC_ENTRIES; i++)
4496+ remove_proc_entry(i915_gem_proc_list[i].name, minor->dev_root);
4497+}
4498diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c
4499new file mode 100644
4500index 0000000..0c1b3a0
4501--- /dev/null
4502+++ b/drivers/gpu/drm/i915/i915_gem_tiling.c
4503@@ -0,0 +1,256 @@
4504+/*
4505+ * Copyright © 2008 Intel Corporation
4506+ *
4507+ * Permission is hereby granted, free of charge, to any person obtaining a
4508+ * copy of this software and associated documentation files (the "Software"),
4509+ * to deal in the Software without restriction, including without limitation
4510+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
4511+ * and/or sell copies of the Software, and to permit persons to whom the
4512+ * Software is furnished to do so, subject to the following conditions:
4513+ *
4514+ * The above copyright notice and this permission notice (including the next
4515+ * paragraph) shall be included in all copies or substantial portions of the
4516+ * Software.
4517+ *
4518+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
4519+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
4520+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
4521+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
4522+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
4523+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
4524+ * IN THE SOFTWARE.
4525+ *
4526+ * Authors:
4527+ * Eric Anholt <eric@anholt.net>
4528+ *
4529+ */
4530+
4531+#include "drmP.h"
4532+#include "drm.h"
4533+#include "i915_drm.h"
4534+#include "i915_drv.h"
4535+
4536+/** @file i915_gem_tiling.c
4537+ *
4538+ * Support for managing tiling state of buffer objects.
4539+ *
4540+ * The idea behind tiling is to increase cache hit rates by rearranging
4541+ * pixel data so that a group of pixel accesses are in the same cacheline.
4542+ * Performance improvement from doing this on the back/depth buffer are on
4543+ * the order of 30%.
4544+ *
4545+ * Intel architectures make this somewhat more complicated, though, by
4546+ * adjustments made to addressing of data when the memory is in interleaved
4547+ * mode (matched pairs of DIMMS) to improve memory bandwidth.
4548+ * For interleaved memory, the CPU sends every sequential 64 bytes
4549+ * to an alternate memory channel so it can get the bandwidth from both.
4550+ *
4551+ * The GPU also rearranges its accesses for increased bandwidth to interleaved
4552+ * memory, and it matches what the CPU does for non-tiled. However, when tiled
4553+ * it does it a little differently, since one walks addresses not just in the
4554+ * X direction but also Y. So, along with alternating channels when bit
4555+ * 6 of the address flips, it also alternates when other bits flip -- Bits 9
4556+ * (every 512 bytes, an X tile scanline) and 10 (every two X tile scanlines)
4557+ * are common to both the 915 and 965-class hardware.
4558+ *
4559+ * The CPU also sometimes XORs in higher bits as well, to improve
4560+ * bandwidth doing strided access like we do so frequently in graphics. This
4561+ * is called "Channel XOR Randomization" in the MCH documentation. The result
4562+ * is that the CPU is XORing in either bit 11 or bit 17 to bit 6 of its address
4563+ * decode.
4564+ *
4565+ * All of this bit 6 XORing has an effect on our memory management,
4566+ * as we need to make sure that the 3d driver can correctly address object
4567+ * contents.
4568+ *
4569+ * If we don't have interleaved memory, all tiling is safe and no swizzling is
4570+ * required.
4571+ *
4572+ * When bit 17 is XORed in, we simply refuse to tile at all. Bit
4573+ * 17 is not just a page offset, so as we page an objet out and back in,
4574+ * individual pages in it will have different bit 17 addresses, resulting in
4575+ * each 64 bytes being swapped with its neighbor!
4576+ *
4577+ * Otherwise, if interleaved, we have to tell the 3d driver what the address
4578+ * swizzling it needs to do is, since it's writing with the CPU to the pages
4579+ * (bit 6 and potentially bit 11 XORed in), and the GPU is reading from the
4580+ * pages (bit 6, 9, and 10 XORed in), resulting in a cumulative bit swizzling
4581+ * required by the CPU of XORing in bit 6, 9, 10, and potentially 11, in order
4582+ * to match what the GPU expects.
4583+ */
4584+
4585+/**
4586+ * Detects bit 6 swizzling of address lookup between IGD access and CPU
4587+ * access through main memory.
4588+ */
4589+void
4590+i915_gem_detect_bit_6_swizzle(struct drm_device *dev)
4591+{
4592+ drm_i915_private_t *dev_priv = dev->dev_private;
4593+ uint32_t swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN;
4594+ uint32_t swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN;
4595+
4596+ if (!IS_I9XX(dev)) {
4597+ /* As far as we know, the 865 doesn't have these bit 6
4598+ * swizzling issues.
4599+ */
4600+ swizzle_x = I915_BIT_6_SWIZZLE_NONE;
4601+ swizzle_y = I915_BIT_6_SWIZZLE_NONE;
4602+ } else if (!IS_I965G(dev) || IS_I965GM(dev)) {
4603+ uint32_t dcc;
4604+
4605+ /* On 915-945 and GM965, channel interleave by the CPU is
4606+ * determined by DCC. The CPU will alternate based on bit 6
4607+ * in interleaved mode, and the GPU will then also alternate
4608+ * on bit 6, 9, and 10 for X, but the CPU may also optionally
4609+ * alternate based on bit 17 (XOR not disabled and XOR
4610+ * bit == 17).
4611+ */
4612+ dcc = I915_READ(DCC);
4613+ switch (dcc & DCC_ADDRESSING_MODE_MASK) {
4614+ case DCC_ADDRESSING_MODE_SINGLE_CHANNEL:
4615+ case DCC_ADDRESSING_MODE_DUAL_CHANNEL_ASYMMETRIC:
4616+ swizzle_x = I915_BIT_6_SWIZZLE_NONE;
4617+ swizzle_y = I915_BIT_6_SWIZZLE_NONE;
4618+ break;
4619+ case DCC_ADDRESSING_MODE_DUAL_CHANNEL_INTERLEAVED:
4620+ if (IS_I915G(dev) || IS_I915GM(dev) ||
4621+ dcc & DCC_CHANNEL_XOR_DISABLE) {
4622+ swizzle_x = I915_BIT_6_SWIZZLE_9_10;
4623+ swizzle_y = I915_BIT_6_SWIZZLE_9;
4624+ } else if (IS_I965GM(dev)) {
4625+ /* GM965 only does bit 11-based channel
4626+ * randomization
4627+ */
4628+ swizzle_x = I915_BIT_6_SWIZZLE_9_10_11;
4629+ swizzle_y = I915_BIT_6_SWIZZLE_9_11;
4630+ } else {
4631+ /* Bit 17 or perhaps other swizzling */
4632+ swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN;
4633+ swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN;
4634+ }
4635+ break;
4636+ }
4637+ if (dcc == 0xffffffff) {
4638+ DRM_ERROR("Couldn't read from MCHBAR. "
4639+ "Disabling tiling.\n");
4640+ swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN;
4641+ swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN;
4642+ }
4643+ } else {
4644+ /* The 965, G33, and newer, have a very flexible memory
4645+ * configuration. It will enable dual-channel mode
4646+ * (interleaving) on as much memory as it can, and the GPU
4647+ * will additionally sometimes enable different bit 6
4648+ * swizzling for tiled objects from the CPU.
4649+ *
4650+ * Here's what I found on the G965:
4651+ * slot fill memory size swizzling
4652+ * 0A 0B 1A 1B 1-ch 2-ch
4653+ * 512 0 0 0 512 0 O
4654+ * 512 0 512 0 16 1008 X
4655+ * 512 0 0 512 16 1008 X
4656+ * 0 512 0 512 16 1008 X
4657+ * 1024 1024 1024 0 2048 1024 O
4658+ *
4659+ * We could probably detect this based on either the DRB
4660+ * matching, which was the case for the swizzling required in
4661+ * the table above, or from the 1-ch value being less than
4662+ * the minimum size of a rank.
4663+ */
4664+ if (I915_READ16(C0DRB3) != I915_READ16(C1DRB3)) {
4665+ swizzle_x = I915_BIT_6_SWIZZLE_NONE;
4666+ swizzle_y = I915_BIT_6_SWIZZLE_NONE;
4667+ } else {
4668+ swizzle_x = I915_BIT_6_SWIZZLE_9_10;
4669+ swizzle_y = I915_BIT_6_SWIZZLE_9;
4670+ }
4671+ }
4672+
4673+ dev_priv->mm.bit_6_swizzle_x = swizzle_x;
4674+ dev_priv->mm.bit_6_swizzle_y = swizzle_y;
4675+}
4676+
4677+/**
4678+ * Sets the tiling mode of an object, returning the required swizzling of
4679+ * bit 6 of addresses in the object.
4680+ */
4681+int
4682+i915_gem_set_tiling(struct drm_device *dev, void *data,
4683+ struct drm_file *file_priv)
4684+{
4685+ struct drm_i915_gem_set_tiling *args = data;
4686+ drm_i915_private_t *dev_priv = dev->dev_private;
4687+ struct drm_gem_object *obj;
4688+ struct drm_i915_gem_object *obj_priv;
4689+
4690+ obj = drm_gem_object_lookup(dev, file_priv, args->handle);
4691+ if (obj == NULL)
4692+ return -EINVAL;
4693+ obj_priv = obj->driver_private;
4694+
4695+ mutex_lock(&dev->struct_mutex);
4696+
4697+ if (args->tiling_mode == I915_TILING_NONE) {
4698+ obj_priv->tiling_mode = I915_TILING_NONE;
4699+ args->swizzle_mode = I915_BIT_6_SWIZZLE_NONE;
4700+ } else {
4701+ if (args->tiling_mode == I915_TILING_X)
4702+ args->swizzle_mode = dev_priv->mm.bit_6_swizzle_x;
4703+ else
4704+ args->swizzle_mode = dev_priv->mm.bit_6_swizzle_y;
4705+ /* If we can't handle the swizzling, make it untiled. */
4706+ if (args->swizzle_mode == I915_BIT_6_SWIZZLE_UNKNOWN) {
4707+ args->tiling_mode = I915_TILING_NONE;
4708+ args->swizzle_mode = I915_BIT_6_SWIZZLE_NONE;
4709+ }
4710+ }
4711+ obj_priv->tiling_mode = args->tiling_mode;
4712+
4713+ mutex_unlock(&dev->struct_mutex);
4714+
4715+ drm_gem_object_unreference(obj);
4716+
4717+ return 0;
4718+}
4719+
4720+/**
4721+ * Returns the current tiling mode and required bit 6 swizzling for the object.
4722+ */
4723+int
4724+i915_gem_get_tiling(struct drm_device *dev, void *data,
4725+ struct drm_file *file_priv)
4726+{
4727+ struct drm_i915_gem_get_tiling *args = data;
4728+ drm_i915_private_t *dev_priv = dev->dev_private;
4729+ struct drm_gem_object *obj;
4730+ struct drm_i915_gem_object *obj_priv;
4731+
4732+ obj = drm_gem_object_lookup(dev, file_priv, args->handle);
4733+ if (obj == NULL)
4734+ return -EINVAL;
4735+ obj_priv = obj->driver_private;
4736+
4737+ mutex_lock(&dev->struct_mutex);
4738+
4739+ args->tiling_mode = obj_priv->tiling_mode;
4740+ switch (obj_priv->tiling_mode) {
4741+ case I915_TILING_X:
4742+ args->swizzle_mode = dev_priv->mm.bit_6_swizzle_x;
4743+ break;
4744+ case I915_TILING_Y:
4745+ args->swizzle_mode = dev_priv->mm.bit_6_swizzle_y;
4746+ break;
4747+ case I915_TILING_NONE:
4748+ args->swizzle_mode = I915_BIT_6_SWIZZLE_NONE;
4749+ break;
4750+ default:
4751+ DRM_ERROR("unknown tiling mode\n");
4752+ }
4753+
4754+ mutex_unlock(&dev->struct_mutex);
4755+
4756+ drm_gem_object_unreference(obj);
4757+
4758+ return 0;
4759+}
4760diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
4761index f875959..f295bdf 100644
4762--- a/drivers/gpu/drm/i915/i915_irq.c
4763+++ b/drivers/gpu/drm/i915/i915_irq.c
4764@@ -407,15 +407,20 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
4765 I915_WRITE(PIPEBSTAT, pipeb_stats);
4766 }
4767
4768- if (iir & I915_ASLE_INTERRUPT)
4769- opregion_asle_intr(dev);
4770+ I915_WRITE(IIR, iir);
4771+ if (dev->pdev->msi_enabled)
4772+ I915_WRITE(IMR, dev_priv->irq_mask_reg);
4773+ (void) I915_READ(IIR); /* Flush posted writes */
4774
4775 dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
4776
4777- if (dev->pdev->msi_enabled)
4778- I915_WRITE(IMR, dev_priv->irq_mask_reg);
4779- I915_WRITE(IIR, iir);
4780- (void) I915_READ(IIR);
4781+ if (iir & I915_USER_INTERRUPT) {
4782+ dev_priv->mm.irq_gem_seqno = i915_get_gem_seqno(dev);
4783+ DRM_WAKEUP(&dev_priv->irq_queue);
4784+ }
4785+
4786+ if (iir & I915_ASLE_INTERRUPT)
4787+ opregion_asle_intr(dev);
4788
4789 if (vblank && dev_priv->swaps_pending > 0)
4790 drm_locked_tasklet(dev, i915_vblank_tasklet);
4791@@ -449,7 +454,7 @@ static int i915_emit_irq(struct drm_device * dev)
4792 return dev_priv->counter;
4793 }
4794
4795-static void i915_user_irq_get(struct drm_device *dev)
4796+void i915_user_irq_get(struct drm_device *dev)
4797 {
4798 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
4799
4800diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
4801index 43ad2cb..5c2d9f2 100644
4802--- a/drivers/gpu/drm/i915/i915_reg.h
4803+++ b/drivers/gpu/drm/i915/i915_reg.h
4804@@ -25,19 +25,6 @@
4805 #ifndef _I915_REG_H_
4806 #define _I915_REG_H_
4807
4808-/* MCH MMIO space */
4809-/** 915-945 and GM965 MCH register controlling DRAM channel access */
4810-#define DCC 0x200
4811-#define DCC_ADDRESSING_MODE_SINGLE_CHANNEL (0 << 0)
4812-#define DCC_ADDRESSING_MODE_DUAL_CHANNEL_ASYMMETRIC (1 << 0)
4813-#define DCC_ADDRESSING_MODE_DUAL_CHANNEL_INTERLEAVED (2 << 0)
4814-#define DCC_ADDRESSING_MODE_MASK (3 << 0)
4815-#define DCC_CHANNEL_XOR_DISABLE (1 << 10)
4816-
4817-/** 965 MCH register controlling DRAM channel configuration */
4818-#define CHDECMISC 0x111
4819-#define CHDECMISC_FLEXMEMORY (1 << 1)
4820-
4821 /*
4822 * The Bridge device's PCI config space has information about the
4823 * fb aperture size and the amount of pre-reserved memory.
4824@@ -516,6 +503,30 @@
4825 #define PALETTE_A 0x0a000
4826 #define PALETTE_B 0x0a800
4827
4828+/* MCH MMIO space */
4829+
4830+/*
4831+ * MCHBAR mirror.
4832+ *
4833+ * This mirrors the MCHBAR MMIO space whose location is determined by
4834+ * device 0 function 0's pci config register 0x44 or 0x48 and matches it in
4835+ * every way. It is not accessible from the CP register read instructions.
4836+ *
4837+ */
4838+#define MCHBAR_MIRROR_BASE 0x10000
4839+
4840+/** 915-945 and GM965 MCH register controlling DRAM channel access */
4841+#define DCC 0x10200
4842+#define DCC_ADDRESSING_MODE_SINGLE_CHANNEL (0 << 0)
4843+#define DCC_ADDRESSING_MODE_DUAL_CHANNEL_ASYMMETRIC (1 << 0)
4844+#define DCC_ADDRESSING_MODE_DUAL_CHANNEL_INTERLEAVED (2 << 0)
4845+#define DCC_ADDRESSING_MODE_MASK (3 << 0)
4846+#define DCC_CHANNEL_XOR_DISABLE (1 << 10)
4847+
4848+/** 965 MCH register controlling DRAM channel configuration */
4849+#define C0DRB3 0x10206
4850+#define C1DRB3 0x10606
4851+
4852 /*
4853 * Overlay regs
4854 */
4855diff --git a/include/drm/drm.h b/include/drm/drm.h
4856index 15e5503..f46ba4b 100644
4857--- a/include/drm/drm.h
4858+++ b/include/drm/drm.h
4859@@ -570,6 +570,34 @@ struct drm_set_version {
4860 int drm_dd_minor;
4861 };
4862
4863+/** DRM_IOCTL_GEM_CLOSE ioctl argument type */
4864+struct drm_gem_close {
4865+ /** Handle of the object to be closed. */
4866+ uint32_t handle;
4867+ uint32_t pad;
4868+};
4869+
4870+/** DRM_IOCTL_GEM_FLINK ioctl argument type */
4871+struct drm_gem_flink {
4872+ /** Handle for the object being named */
4873+ uint32_t handle;
4874+
4875+ /** Returned global name */
4876+ uint32_t name;
4877+};
4878+
4879+/** DRM_IOCTL_GEM_OPEN ioctl argument type */
4880+struct drm_gem_open {
4881+ /** Name of object being opened */
4882+ uint32_t name;
4883+
4884+ /** Returned handle for the object */
4885+ uint32_t handle;
4886+
4887+ /** Returned size of the object */
4888+ uint64_t size;
4889+};
4890+
4891 #define DRM_IOCTL_BASE 'd'
4892 #define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr)
4893 #define DRM_IOR(nr,type) _IOR(DRM_IOCTL_BASE,nr,type)
4894@@ -585,6 +613,9 @@ struct drm_set_version {
4895 #define DRM_IOCTL_GET_STATS DRM_IOR( 0x06, struct drm_stats)
4896 #define DRM_IOCTL_SET_VERSION DRM_IOWR(0x07, struct drm_set_version)
4897 #define DRM_IOCTL_MODESET_CTL DRM_IOW(0x08, struct drm_modeset_ctl)
4898+#define DRM_IOCTL_GEM_CLOSE DRM_IOW (0x09, struct drm_gem_close)
4899+#define DRM_IOCTL_GEM_FLINK DRM_IOWR(0x0a, struct drm_gem_flink)
4900+#define DRM_IOCTL_GEM_OPEN DRM_IOWR(0x0b, struct drm_gem_open)
4901
4902 #define DRM_IOCTL_SET_UNIQUE DRM_IOW( 0x10, struct drm_unique)
4903 #define DRM_IOCTL_AUTH_MAGIC DRM_IOW( 0x11, struct drm_auth)
4904diff --git a/include/drm/drmP.h b/include/drm/drmP.h
4905index e79ce07..1469a1b 100644
4906--- a/include/drm/drmP.h
4907+++ b/include/drm/drmP.h
4908@@ -104,6 +104,7 @@ struct drm_device;
4909 #define DRIVER_DMA_QUEUE 0x200
4910 #define DRIVER_FB_DMA 0x400
4911 #define DRIVER_IRQ_VBL2 0x800
4912+#define DRIVER_GEM 0x1000
4913
4914 /***********************************************************************/
4915 /** \name Begin the DRM... */
4916@@ -387,6 +388,10 @@ struct drm_file {
4917 struct drm_minor *minor;
4918 int remove_auth_on_close;
4919 unsigned long lock_count;
4920+ /** Mapping of mm object handles to object pointers. */
4921+ struct idr object_idr;
4922+ /** Lock for synchronization of access to object_idr. */
4923+ spinlock_t table_lock;
4924 struct file *filp;
4925 void *driver_priv;
4926 };
4927@@ -558,6 +563,56 @@ struct drm_ati_pcigart_info {
4928 };
4929
4930 /**
4931+ * This structure defines the drm_mm memory object, which will be used by the
4932+ * DRM for its buffer objects.
4933+ */
4934+struct drm_gem_object {
4935+ /** Reference count of this object */
4936+ struct kref refcount;
4937+
4938+ /** Handle count of this object. Each handle also holds a reference */
4939+ struct kref handlecount;
4940+
4941+ /** Related drm device */
4942+ struct drm_device *dev;
4943+
4944+ /** File representing the shmem storage */
4945+ struct file *filp;
4946+
4947+ /**
4948+ * Size of the object, in bytes. Immutable over the object's
4949+ * lifetime.
4950+ */
4951+ size_t size;
4952+
4953+ /**
4954+ * Global name for this object, starts at 1. 0 means unnamed.
4955+ * Access is covered by the object_name_lock in the related drm_device
4956+ */
4957+ int name;
4958+
4959+ /**
4960+ * Memory domains. These monitor which caches contain read/write data
4961+ * related to the object. When transitioning from one set of domains
4962+ * to another, the driver is called to ensure that caches are suitably
4963+ * flushed and invalidated
4964+ */
4965+ uint32_t read_domains;
4966+ uint32_t write_domain;
4967+
4968+ /**
4969+ * While validating an exec operation, the
4970+ * new read/write domain values are computed here.
4971+ * They will be transferred to the above values
4972+ * at the point that any cache flushing occurs
4973+ */
4974+ uint32_t pending_read_domains;
4975+ uint32_t pending_write_domain;
4976+
4977+ void *driver_private;
4978+};
4979+
4980+/**
4981 * DRM driver structure. This structure represent the common code for
4982 * a family of cards. There will one drm_device for each card present
4983 * in this family
4984@@ -657,6 +712,18 @@ struct drm_driver {
4985 void (*set_version) (struct drm_device *dev,
4986 struct drm_set_version *sv);
4987
4988+ int (*proc_init)(struct drm_minor *minor);
4989+ void (*proc_cleanup)(struct drm_minor *minor);
4990+
4991+ /**
4992+ * Driver-specific constructor for drm_gem_objects, to set up
4993+ * obj->driver_private.
4994+ *
4995+ * Returns 0 on success.
4996+ */
4997+ int (*gem_init_object) (struct drm_gem_object *obj);
4998+ void (*gem_free_object) (struct drm_gem_object *obj);
4999+
5000 int major;
5001 int minor;
5002 int patchlevel;
5003@@ -830,6 +897,22 @@ struct drm_device {
5004 spinlock_t drw_lock;
5005 struct idr drw_idr;
5006 /*@} */
5007+
5008+ /** \name GEM information */
5009+ /*@{ */
5010+ spinlock_t object_name_lock;
5011+ struct idr object_name_idr;
5012+ atomic_t object_count;
5013+ atomic_t object_memory;
5014+ atomic_t pin_count;
5015+ atomic_t pin_memory;
5016+ atomic_t gtt_count;
5017+ atomic_t gtt_memory;
5018+ uint32_t gtt_total;
5019+ uint32_t invalidate_domains; /* domains pending invalidation */
5020+ uint32_t flush_domains; /* domains pending flush */
5021+ /*@} */
5022+
5023 };
5024
5025 static __inline__ int drm_core_check_feature(struct drm_device *dev,
5026@@ -926,6 +1009,10 @@ extern void *drm_realloc(void *oldpt, size_t oldsize, size_t size, int area);
5027 extern DRM_AGP_MEM *drm_alloc_agp(struct drm_device *dev, int pages, u32 type);
5028 extern int drm_free_agp(DRM_AGP_MEM * handle, int pages);
5029 extern int drm_bind_agp(DRM_AGP_MEM * handle, unsigned int start);
5030+extern DRM_AGP_MEM *drm_agp_bind_pages(struct drm_device *dev,
5031+ struct page **pages,
5032+ unsigned long num_pages,
5033+ uint32_t gtt_offset);
5034 extern int drm_unbind_agp(DRM_AGP_MEM * handle);
5035
5036 /* Misc. IOCTL support (drm_ioctl.h) */
5037@@ -988,6 +1075,9 @@ extern int drm_getmagic(struct drm_device *dev, void *data,
5038 extern int drm_authmagic(struct drm_device *dev, void *data,
5039 struct drm_file *file_priv);
5040
5041+/* Cache management (drm_cache.c) */
5042+void drm_clflush_pages(struct page *pages[], unsigned long num_pages);
5043+
5044 /* Locking IOCTL support (drm_lock.h) */
5045 extern int drm_lock(struct drm_device *dev, void *data,
5046 struct drm_file *file_priv);
5047@@ -1094,6 +1184,7 @@ extern DRM_AGP_MEM *drm_agp_allocate_memory(struct agp_bridge_data *bridge, size
5048 extern int drm_agp_free_memory(DRM_AGP_MEM * handle);
5049 extern int drm_agp_bind_memory(DRM_AGP_MEM * handle, off_t start);
5050 extern int drm_agp_unbind_memory(DRM_AGP_MEM * handle);
5051+extern void drm_agp_chipset_flush(struct drm_device *dev);
5052
5053 /* Stub support (drm_stub.h) */
5054 extern int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
5055@@ -1156,6 +1247,66 @@ extern unsigned long drm_mm_tail_space(struct drm_mm *mm);
5056 extern int drm_mm_remove_space_from_tail(struct drm_mm *mm, unsigned long size);
5057 extern int drm_mm_add_space_to_tail(struct drm_mm *mm, unsigned long size);
5058
5059+/* Graphics Execution Manager library functions (drm_gem.c) */
5060+int drm_gem_init(struct drm_device *dev);
5061+void drm_gem_object_free(struct kref *kref);
5062+struct drm_gem_object *drm_gem_object_alloc(struct drm_device *dev,
5063+ size_t size);
5064+void drm_gem_object_handle_free(struct kref *kref);
5065+
5066+static inline void
5067+drm_gem_object_reference(struct drm_gem_object *obj)
5068+{
5069+ kref_get(&obj->refcount);
5070+}
5071+
5072+static inline void
5073+drm_gem_object_unreference(struct drm_gem_object *obj)
5074+{
5075+ if (obj == NULL)
5076+ return;
5077+
5078+ kref_put(&obj->refcount, drm_gem_object_free);
5079+}
5080+
5081+int drm_gem_handle_create(struct drm_file *file_priv,
5082+ struct drm_gem_object *obj,
5083+ int *handlep);
5084+
5085+static inline void
5086+drm_gem_object_handle_reference(struct drm_gem_object *obj)
5087+{
5088+ drm_gem_object_reference(obj);
5089+ kref_get(&obj->handlecount);
5090+}
5091+
5092+static inline void
5093+drm_gem_object_handle_unreference(struct drm_gem_object *obj)
5094+{
5095+ if (obj == NULL)
5096+ return;
5097+
5098+ /*
5099+ * Must bump handle count first as this may be the last
5100+ * ref, in which case the object would disappear before we
5101+ * checked for a name
5102+ */
5103+ kref_put(&obj->handlecount, drm_gem_object_handle_free);
5104+ drm_gem_object_unreference(obj);
5105+}
5106+
5107+struct drm_gem_object *drm_gem_object_lookup(struct drm_device *dev,
5108+ struct drm_file *filp,
5109+ int handle);
5110+int drm_gem_close_ioctl(struct drm_device *dev, void *data,
5111+ struct drm_file *file_priv);
5112+int drm_gem_flink_ioctl(struct drm_device *dev, void *data,
5113+ struct drm_file *file_priv);
5114+int drm_gem_open_ioctl(struct drm_device *dev, void *data,
5115+ struct drm_file *file_priv);
5116+void drm_gem_open(struct drm_device *dev, struct drm_file *file_private);
5117+void drm_gem_release(struct drm_device *dev, struct drm_file *file_private);
5118+
5119 extern void drm_core_ioremap(struct drm_map *map, struct drm_device *dev);
5120 extern void drm_core_ioremap_wc(struct drm_map *map, struct drm_device *dev);
5121 extern void drm_core_ioremapfree(struct drm_map *map, struct drm_device *dev);
5122diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h
5123index 05c66cf..59d08fc 100644
5124--- a/include/drm/i915_drm.h
5125+++ b/include/drm/i915_drm.h
5126@@ -143,6 +143,22 @@ typedef struct _drm_i915_sarea {
5127 #define DRM_I915_GET_VBLANK_PIPE 0x0e
5128 #define DRM_I915_VBLANK_SWAP 0x0f
5129 #define DRM_I915_HWS_ADDR 0x11
5130+#define DRM_I915_GEM_INIT 0x13
5131+#define DRM_I915_GEM_EXECBUFFER 0x14
5132+#define DRM_I915_GEM_PIN 0x15
5133+#define DRM_I915_GEM_UNPIN 0x16
5134+#define DRM_I915_GEM_BUSY 0x17
5135+#define DRM_I915_GEM_THROTTLE 0x18
5136+#define DRM_I915_GEM_ENTERVT 0x19
5137+#define DRM_I915_GEM_LEAVEVT 0x1a
5138+#define DRM_I915_GEM_CREATE 0x1b
5139+#define DRM_I915_GEM_PREAD 0x1c
5140+#define DRM_I915_GEM_PWRITE 0x1d
5141+#define DRM_I915_GEM_MMAP 0x1e
5142+#define DRM_I915_GEM_SET_DOMAIN 0x1f
5143+#define DRM_I915_GEM_SW_FINISH 0x20
5144+#define DRM_I915_GEM_SET_TILING 0x21
5145+#define DRM_I915_GEM_GET_TILING 0x22
5146
5147 #define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t)
5148 #define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH)
5149@@ -160,6 +176,20 @@ typedef struct _drm_i915_sarea {
5150 #define DRM_IOCTL_I915_SET_VBLANK_PIPE DRM_IOW( DRM_COMMAND_BASE + DRM_I915_SET_VBLANK_PIPE, drm_i915_vblank_pipe_t)
5151 #define DRM_IOCTL_I915_GET_VBLANK_PIPE DRM_IOR( DRM_COMMAND_BASE + DRM_I915_GET_VBLANK_PIPE, drm_i915_vblank_pipe_t)
5152 #define DRM_IOCTL_I915_VBLANK_SWAP DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_VBLANK_SWAP, drm_i915_vblank_swap_t)
5153+#define DRM_IOCTL_I915_GEM_PIN DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_PIN, struct drm_i915_gem_pin)
5154+#define DRM_IOCTL_I915_GEM_UNPIN DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_UNPIN, struct drm_i915_gem_unpin)
5155+#define DRM_IOCTL_I915_GEM_BUSY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_BUSY, struct drm_i915_gem_busy)
5156+#define DRM_IOCTL_I915_GEM_THROTTLE DRM_IO ( DRM_COMMAND_BASE + DRM_I915_GEM_THROTTLE)
5157+#define DRM_IOCTL_I915_GEM_ENTERVT DRM_IO(DRM_COMMAND_BASE + DRM_I915_GEM_ENTERVT)
5158+#define DRM_IOCTL_I915_GEM_LEAVEVT DRM_IO(DRM_COMMAND_BASE + DRM_I915_GEM_LEAVEVT)
5159+#define DRM_IOCTL_I915_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_CREATE, struct drm_i915_gem_create)
5160+#define DRM_IOCTL_I915_GEM_PREAD DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_PREAD, struct drm_i915_gem_pread)
5161+#define DRM_IOCTL_I915_GEM_PWRITE DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_PWRITE, struct drm_i915_gem_pwrite)
5162+#define DRM_IOCTL_I915_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MMAP, struct drm_i915_gem_mmap)
5163+#define DRM_IOCTL_I915_GEM_SET_DOMAIN DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_SET_DOMAIN, struct drm_i915_gem_set_domain)
5164+#define DRM_IOCTL_I915_GEM_SW_FINISH DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_SW_FINISH, struct drm_i915_gem_sw_finish)
5165+#define DRM_IOCTL_I915_GEM_SET_TILING DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_SET_TILING, struct drm_i915_gem_set_tiling)
5166+#define DRM_IOCTL_I915_GEM_GET_TILING DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_GET_TILING, struct drm_i915_gem_get_tiling)
5167
5168 /* Allow drivers to submit batchbuffers directly to hardware, relying
5169 * on the security mechanisms provided by hardware.
5170@@ -200,6 +230,7 @@ typedef struct drm_i915_irq_wait {
5171 #define I915_PARAM_IRQ_ACTIVE 1
5172 #define I915_PARAM_ALLOW_BATCHBUFFER 2
5173 #define I915_PARAM_LAST_DISPATCH 3
5174+#define I915_PARAM_HAS_GEM 5
5175
5176 typedef struct drm_i915_getparam {
5177 int param;
5178@@ -267,4 +298,305 @@ typedef struct drm_i915_hws_addr {
5179 uint64_t addr;
5180 } drm_i915_hws_addr_t;
5181
5182+struct drm_i915_gem_init {
5183+ /**
5184+ * Beginning offset in the GTT to be managed by the DRM memory
5185+ * manager.
5186+ */
5187+ uint64_t gtt_start;
5188+ /**
5189+ * Ending offset in the GTT to be managed by the DRM memory
5190+ * manager.
5191+ */
5192+ uint64_t gtt_end;
5193+};
5194+
5195+struct drm_i915_gem_create {
5196+ /**
5197+ * Requested size for the object.
5198+ *
5199+ * The (page-aligned) allocated size for the object will be returned.
5200+ */
5201+ uint64_t size;
5202+ /**
5203+ * Returned handle for the object.
5204+ *
5205+ * Object handles are nonzero.
5206+ */
5207+ uint32_t handle;
5208+ uint32_t pad;
5209+};
5210+
5211+struct drm_i915_gem_pread {
5212+ /** Handle for the object being read. */
5213+ uint32_t handle;
5214+ uint32_t pad;
5215+ /** Offset into the object to read from */
5216+ uint64_t offset;
5217+ /** Length of data to read */
5218+ uint64_t size;
5219+ /**
5220+ * Pointer to write the data into.
5221+ *
5222+ * This is a fixed-size type for 32/64 compatibility.
5223+ */
5224+ uint64_t data_ptr;
5225+};
5226+
5227+struct drm_i915_gem_pwrite {
5228+ /** Handle for the object being written to. */
5229+ uint32_t handle;
5230+ uint32_t pad;
5231+ /** Offset into the object to write to */
5232+ uint64_t offset;
5233+ /** Length of data to write */
5234+ uint64_t size;
5235+ /**
5236+ * Pointer to read the data from.
5237+ *
5238+ * This is a fixed-size type for 32/64 compatibility.
5239+ */
5240+ uint64_t data_ptr;
5241+};
5242+
5243+struct drm_i915_gem_mmap {
5244+ /** Handle for the object being mapped. */
5245+ uint32_t handle;
5246+ uint32_t pad;
5247+ /** Offset in the object to map. */
5248+ uint64_t offset;
5249+ /**
5250+ * Length of data to map.
5251+ *
5252+ * The value will be page-aligned.
5253+ */
5254+ uint64_t size;
5255+ /**
5256+ * Returned pointer the data was mapped at.
5257+ *
5258+ * This is a fixed-size type for 32/64 compatibility.
5259+ */
5260+ uint64_t addr_ptr;
5261+};
5262+
5263+struct drm_i915_gem_set_domain {
5264+ /** Handle for the object */
5265+ uint32_t handle;
5266+
5267+ /** New read domains */
5268+ uint32_t read_domains;
5269+
5270+ /** New write domain */
5271+ uint32_t write_domain;
5272+};
5273+
5274+struct drm_i915_gem_sw_finish {
5275+ /** Handle for the object */
5276+ uint32_t handle;
5277+};
5278+
5279+struct drm_i915_gem_relocation_entry {
5280+ /**
5281+ * Handle of the buffer being pointed to by this relocation entry.
5282+ *
5283+ * It's appealing to make this be an index into the mm_validate_entry
5284+ * list to refer to the buffer, but this allows the driver to create
5285+ * a relocation list for state buffers and not re-write it per
5286+ * exec using the buffer.
5287+ */
5288+ uint32_t target_handle;
5289+
5290+ /**
5291+ * Value to be added to the offset of the target buffer to make up
5292+ * the relocation entry.
5293+ */
5294+ uint32_t delta;
5295+
5296+ /** Offset in the buffer the relocation entry will be written into */
5297+ uint64_t offset;
5298+
5299+ /**
5300+ * Offset value of the target buffer that the relocation entry was last
5301+ * written as.
5302+ *
5303+ * If the buffer has the same offset as last time, we can skip syncing
5304+ * and writing the relocation. This value is written back out by
5305+ * the execbuffer ioctl when the relocation is written.
5306+ */
5307+ uint64_t presumed_offset;
5308+
5309+ /**
5310+ * Target memory domains read by this operation.
5311+ */
5312+ uint32_t read_domains;
5313+
5314+ /**
5315+ * Target memory domains written by this operation.
5316+ *
5317+ * Note that only one domain may be written by the whole
5318+ * execbuffer operation, so that where there are conflicts,
5319+ * the application will get -EINVAL back.
5320+ */
5321+ uint32_t write_domain;
5322+};
5323+
5324+/** @{
5325+ * Intel memory domains
5326+ *
5327+ * Most of these just align with the various caches in
5328+ * the system and are used to flush and invalidate as
5329+ * objects end up cached in different domains.
5330+ */
5331+/** CPU cache */
5332+#define I915_GEM_DOMAIN_CPU 0x00000001
5333+/** Render cache, used by 2D and 3D drawing */
5334+#define I915_GEM_DOMAIN_RENDER 0x00000002
5335+/** Sampler cache, used by texture engine */
5336+#define I915_GEM_DOMAIN_SAMPLER 0x00000004
5337+/** Command queue, used to load batch buffers */
5338+#define I915_GEM_DOMAIN_COMMAND 0x00000008
5339+/** Instruction cache, used by shader programs */
5340+#define I915_GEM_DOMAIN_INSTRUCTION 0x00000010
5341+/** Vertex address cache */
5342+#define I915_GEM_DOMAIN_VERTEX 0x00000020
5343+/** GTT domain - aperture and scanout */
5344+#define I915_GEM_DOMAIN_GTT 0x00000040
5345+/** @} */
5346+
5347+struct drm_i915_gem_exec_object {
5348+ /**
5349+ * User's handle for a buffer to be bound into the GTT for this
5350+ * operation.
5351+ */
5352+ uint32_t handle;
5353+
5354+ /** Number of relocations to be performed on this buffer */
5355+ uint32_t relocation_count;
5356+ /**
5357+ * Pointer to array of struct drm_i915_gem_relocation_entry containing
5358+ * the relocations to be performed in this buffer.
5359+ */
5360+ uint64_t relocs_ptr;
5361+
5362+ /** Required alignment in graphics aperture */
5363+ uint64_t alignment;
5364+
5365+ /**
5366+ * Returned value of the updated offset of the object, for future
5367+ * presumed_offset writes.
5368+ */
5369+ uint64_t offset;
5370+};
5371+
5372+struct drm_i915_gem_execbuffer {
5373+ /**
5374+ * List of buffers to be validated with their relocations to be
5375+ * performend on them.
5376+ *
5377+ * This is a pointer to an array of struct drm_i915_gem_validate_entry.
5378+ *
5379+ * These buffers must be listed in an order such that all relocations
5380+ * a buffer is performing refer to buffers that have already appeared
5381+ * in the validate list.
5382+ */
5383+ uint64_t buffers_ptr;
5384+ uint32_t buffer_count;
5385+
5386+ /** Offset in the batchbuffer to start execution from. */
5387+ uint32_t batch_start_offset;
5388+ /** Bytes used in batchbuffer from batch_start_offset */
5389+ uint32_t batch_len;
5390+ uint32_t DR1;
5391+ uint32_t DR4;
5392+ uint32_t num_cliprects;
5393+ /** This is a struct drm_clip_rect *cliprects */
5394+ uint64_t cliprects_ptr;
5395+};
5396+
5397+struct drm_i915_gem_pin {
5398+ /** Handle of the buffer to be pinned. */
5399+ uint32_t handle;
5400+ uint32_t pad;
5401+
5402+ /** alignment required within the aperture */
5403+ uint64_t alignment;
5404+
5405+ /** Returned GTT offset of the buffer. */
5406+ uint64_t offset;
5407+};
5408+
5409+struct drm_i915_gem_unpin {
5410+ /** Handle of the buffer to be unpinned. */
5411+ uint32_t handle;
5412+ uint32_t pad;
5413+};
5414+
5415+struct drm_i915_gem_busy {
5416+ /** Handle of the buffer to check for busy */
5417+ uint32_t handle;
5418+
5419+ /** Return busy status (1 if busy, 0 if idle) */
5420+ uint32_t busy;
5421+};
5422+
5423+#define I915_TILING_NONE 0
5424+#define I915_TILING_X 1
5425+#define I915_TILING_Y 2
5426+
5427+#define I915_BIT_6_SWIZZLE_NONE 0
5428+#define I915_BIT_6_SWIZZLE_9 1
5429+#define I915_BIT_6_SWIZZLE_9_10 2
5430+#define I915_BIT_6_SWIZZLE_9_11 3
5431+#define I915_BIT_6_SWIZZLE_9_10_11 4
5432+/* Not seen by userland */
5433+#define I915_BIT_6_SWIZZLE_UNKNOWN 5
5434+
5435+struct drm_i915_gem_set_tiling {
5436+ /** Handle of the buffer to have its tiling state updated */
5437+ uint32_t handle;
5438+
5439+ /**
5440+ * Tiling mode for the object (I915_TILING_NONE, I915_TILING_X,
5441+ * I915_TILING_Y).
5442+ *
5443+ * This value is to be set on request, and will be updated by the
5444+ * kernel on successful return with the actual chosen tiling layout.
5445+ *
5446+ * The tiling mode may be demoted to I915_TILING_NONE when the system
5447+ * has bit 6 swizzling that can't be managed correctly by GEM.
5448+ *
5449+ * Buffer contents become undefined when changing tiling_mode.
5450+ */
5451+ uint32_t tiling_mode;
5452+
5453+ /**
5454+ * Stride in bytes for the object when in I915_TILING_X or
5455+ * I915_TILING_Y.
5456+ */
5457+ uint32_t stride;
5458+
5459+ /**
5460+ * Returned address bit 6 swizzling required for CPU access through
5461+ * mmap mapping.
5462+ */
5463+ uint32_t swizzle_mode;
5464+};
5465+
5466+struct drm_i915_gem_get_tiling {
5467+ /** Handle of the buffer to get tiling state for. */
5468+ uint32_t handle;
5469+
5470+ /**
5471+ * Current tiling mode for the object (I915_TILING_NONE, I915_TILING_X,
5472+ * I915_TILING_Y).
5473+ */
5474+ uint32_t tiling_mode;
5475+
5476+ /**
5477+ * Returned address bit 6 swizzling required for CPU access through
5478+ * mmap mapping.
5479+ */
5480+ uint32_t swizzle_mode;
5481+};
5482+
5483 #endif /* _I915_DRM_H_ */
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0015-i915-Add-chip-set-ID-param.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0015-i915-Add-chip-set-ID-param.patch
new file mode 100644
index 0000000000..c3bf8ebd13
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0015-i915-Add-chip-set-ID-param.patch
@@ -0,0 +1,35 @@
1commit 26ead293ddf664f33dc0ba12b726887c40ce3957
2Author: Kristian Høgsberg <krh@redhat.com>
3Date: Wed Aug 20 11:08:52 2008 -0400
4
5 i915: Add chip set ID param.
6
7 Signed-off-by: Kristian Høgsberg <krh@redhat.com>
8 Signed-off-by: Eric Anholt <eric@anholt.net>
9
10diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
11index 3b5aa74..205d21e 100644
12--- a/drivers/gpu/drm/i915/i915_dma.c
13+++ b/drivers/gpu/drm/i915/i915_dma.c
14@@ -689,6 +689,9 @@ static int i915_getparam(struct drm_device *dev, void *data,
15 case I915_PARAM_LAST_DISPATCH:
16 value = READ_BREADCRUMB(dev_priv);
17 break;
18+ case I915_PARAM_CHIPSET_ID:
19+ value = dev->pci_device;
20+ break;
21 case I915_PARAM_HAS_GEM:
22 value = 1;
23 break;
24diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h
25index 59d08fc..eb4b350 100644
26--- a/include/drm/i915_drm.h
27+++ b/include/drm/i915_drm.h
28@@ -230,6 +230,7 @@ typedef struct drm_i915_irq_wait {
29 #define I915_PARAM_IRQ_ACTIVE 1
30 #define I915_PARAM_ALLOW_BATCHBUFFER 2
31 #define I915_PARAM_LAST_DISPATCH 3
32+#define I915_PARAM_CHIPSET_ID 4
33 #define I915_PARAM_HAS_GEM 5
34
35 typedef struct drm_i915_getparam {
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0016-i915-Use-struct_mutex-to-protect-ring-in-GEM-mode.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0016-i915-Use-struct_mutex-to-protect-ring-in-GEM-mode.patch
new file mode 100644
index 0000000000..910f37e9c5
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0016-i915-Use-struct_mutex-to-protect-ring-in-GEM-mode.patch
@@ -0,0 +1,205 @@
1commit 8a524209fce67d3b6d2e831b5dad4eced796ce98
2Author: Eric Anholt <eric@anholt.net>
3Date: Mon Sep 1 16:45:29 2008 -0700
4
5 i915: Use struct_mutex to protect ring in GEM mode.
6
7 In the conversion for GEM, we had stopped using the hardware lock to protect
8 ring usage, since it was all internal to the DRM now. However, some paths
9 weren't converted to using struct_mutex to prevent multiple threads from
10 concurrently working on the ring, in particular between the vblank swap handler
11 and ioctls.
12
13 Signed-off-by: Eric Anholt <eric@anholt.net>
14
15diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
16index 205d21e..25f59c1 100644
17--- a/drivers/gpu/drm/i915/i915_dma.c
18+++ b/drivers/gpu/drm/i915/i915_dma.c
19@@ -588,9 +588,15 @@ static int i915_quiescent(struct drm_device * dev)
20 static int i915_flush_ioctl(struct drm_device *dev, void *data,
21 struct drm_file *file_priv)
22 {
23- LOCK_TEST_WITH_RETURN(dev, file_priv);
24+ int ret;
25+
26+ RING_LOCK_TEST_WITH_RETURN(dev, file_priv);
27
28- return i915_quiescent(dev);
29+ mutex_lock(&dev->struct_mutex);
30+ ret = i915_quiescent(dev);
31+ mutex_unlock(&dev->struct_mutex);
32+
33+ return ret;
34 }
35
36 static int i915_batchbuffer(struct drm_device *dev, void *data,
37@@ -611,14 +617,16 @@ static int i915_batchbuffer(struct drm_device *dev, void *data,
38 DRM_DEBUG("i915 batchbuffer, start %x used %d cliprects %d\n",
39 batch->start, batch->used, batch->num_cliprects);
40
41- LOCK_TEST_WITH_RETURN(dev, file_priv);
42+ RING_LOCK_TEST_WITH_RETURN(dev, file_priv);
43
44 if (batch->num_cliprects && DRM_VERIFYAREA_READ(batch->cliprects,
45 batch->num_cliprects *
46 sizeof(struct drm_clip_rect)))
47 return -EFAULT;
48
49+ mutex_lock(&dev->struct_mutex);
50 ret = i915_dispatch_batchbuffer(dev, batch);
51+ mutex_unlock(&dev->struct_mutex);
52
53 sarea_priv->last_dispatch = (int)hw_status[5];
54 return ret;
55@@ -637,7 +645,7 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data,
56 DRM_DEBUG("i915 cmdbuffer, buf %p sz %d cliprects %d\n",
57 cmdbuf->buf, cmdbuf->sz, cmdbuf->num_cliprects);
58
59- LOCK_TEST_WITH_RETURN(dev, file_priv);
60+ RING_LOCK_TEST_WITH_RETURN(dev, file_priv);
61
62 if (cmdbuf->num_cliprects &&
63 DRM_VERIFYAREA_READ(cmdbuf->cliprects,
64@@ -647,7 +655,9 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data,
65 return -EFAULT;
66 }
67
68+ mutex_lock(&dev->struct_mutex);
69 ret = i915_dispatch_cmdbuffer(dev, cmdbuf);
70+ mutex_unlock(&dev->struct_mutex);
71 if (ret) {
72 DRM_ERROR("i915_dispatch_cmdbuffer failed\n");
73 return ret;
74@@ -660,11 +670,17 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data,
75 static int i915_flip_bufs(struct drm_device *dev, void *data,
76 struct drm_file *file_priv)
77 {
78+ int ret;
79+
80 DRM_DEBUG("%s\n", __FUNCTION__);
81
82- LOCK_TEST_WITH_RETURN(dev, file_priv);
83+ RING_LOCK_TEST_WITH_RETURN(dev, file_priv);
84
85- return i915_dispatch_flip(dev);
86+ mutex_lock(&dev->struct_mutex);
87+ ret = i915_dispatch_flip(dev);
88+ mutex_unlock(&dev->struct_mutex);
89+
90+ return ret;
91 }
92
93 static int i915_getparam(struct drm_device *dev, void *data,
94diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
95index 87b071a..8547f0a 100644
96--- a/drivers/gpu/drm/i915/i915_drv.h
97+++ b/drivers/gpu/drm/i915/i915_drv.h
98@@ -285,6 +285,9 @@ typedef struct drm_i915_private {
99 */
100 struct delayed_work retire_work;
101
102+ /** Work task for vblank-related ring access */
103+ struct work_struct vblank_work;
104+
105 uint32_t next_gem_seqno;
106
107 /**
108@@ -435,6 +438,7 @@ extern int i915_irq_wait(struct drm_device *dev, void *data,
109 void i915_user_irq_get(struct drm_device *dev);
110 void i915_user_irq_put(struct drm_device *dev);
111
112+extern void i915_gem_vblank_work_handler(struct work_struct *work);
113 extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS);
114 extern void i915_driver_irq_preinstall(struct drm_device * dev);
115 extern int i915_driver_irq_postinstall(struct drm_device *dev);
116@@ -538,6 +542,17 @@ extern void intel_opregion_free(struct drm_device *dev);
117 extern void opregion_asle_intr(struct drm_device *dev);
118 extern void opregion_enable_asle(struct drm_device *dev);
119
120+/**
121+ * Lock test for when it's just for synchronization of ring access.
122+ *
123+ * In that case, we don't need to do it when GEM is initialized as nobody else
124+ * has access to the ring.
125+ */
126+#define RING_LOCK_TEST_WITH_RETURN(dev, file_priv) do { \
127+ if (((drm_i915_private_t *)dev->dev_private)->ring.ring_obj == NULL) \
128+ LOCK_TEST_WITH_RETURN(dev, file_priv); \
129+} while (0)
130+
131 #define I915_READ(reg) DRM_READ32(dev_priv->mmio_map, (reg))
132 #define I915_WRITE(reg,val) DRM_WRITE32(dev_priv->mmio_map, (reg), (val))
133 #define I915_READ16(reg) DRM_READ16(dev_priv->mmio_map, (reg))
134diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
135index 90ae8a0..bb6e5a3 100644
136--- a/drivers/gpu/drm/i915/i915_gem.c
137+++ b/drivers/gpu/drm/i915/i915_gem.c
138@@ -2491,6 +2491,8 @@ i915_gem_load(struct drm_device *dev)
139 INIT_LIST_HEAD(&dev_priv->mm.request_list);
140 INIT_DELAYED_WORK(&dev_priv->mm.retire_work,
141 i915_gem_retire_work_handler);
142+ INIT_WORK(&dev_priv->mm.vblank_work,
143+ i915_gem_vblank_work_handler);
144 dev_priv->mm.next_gem_seqno = 1;
145
146 i915_gem_detect_bit_6_swizzle(dev);
147diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
148index f295bdf..d04c526 100644
149--- a/drivers/gpu/drm/i915/i915_irq.c
150+++ b/drivers/gpu/drm/i915/i915_irq.c
151@@ -349,6 +349,21 @@ u32 i915_get_vblank_counter(struct drm_device *dev, int plane)
152 return count;
153 }
154
155+void
156+i915_gem_vblank_work_handler(struct work_struct *work)
157+{
158+ drm_i915_private_t *dev_priv;
159+ struct drm_device *dev;
160+
161+ dev_priv = container_of(work, drm_i915_private_t,
162+ mm.vblank_work);
163+ dev = dev_priv->dev;
164+
165+ mutex_lock(&dev->struct_mutex);
166+ i915_vblank_tasklet(dev);
167+ mutex_unlock(&dev->struct_mutex);
168+}
169+
170 irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
171 {
172 struct drm_device *dev = (struct drm_device *) arg;
173@@ -422,8 +437,12 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
174 if (iir & I915_ASLE_INTERRUPT)
175 opregion_asle_intr(dev);
176
177- if (vblank && dev_priv->swaps_pending > 0)
178- drm_locked_tasklet(dev, i915_vblank_tasklet);
179+ if (vblank && dev_priv->swaps_pending > 0) {
180+ if (dev_priv->ring.ring_obj == NULL)
181+ drm_locked_tasklet(dev, i915_vblank_tasklet);
182+ else
183+ schedule_work(&dev_priv->mm.vblank_work);
184+ }
185
186 return IRQ_HANDLED;
187 }
188@@ -514,14 +533,15 @@ int i915_irq_emit(struct drm_device *dev, void *data,
189 drm_i915_irq_emit_t *emit = data;
190 int result;
191
192- LOCK_TEST_WITH_RETURN(dev, file_priv);
193+ RING_LOCK_TEST_WITH_RETURN(dev, file_priv);
194
195 if (!dev_priv) {
196 DRM_ERROR("called with no initialization\n");
197 return -EINVAL;
198 }
199-
200+ mutex_lock(&dev->struct_mutex);
201 result = i915_emit_irq(dev);
202+ mutex_unlock(&dev->struct_mutex);
203
204 if (DRM_COPY_TO_USER(emit->irq_seq, &result, sizeof(int))) {
205 DRM_ERROR("copy_to_user\n");
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0017-i915-Make-use-of-sarea_priv-conditional.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0017-i915-Make-use-of-sarea_priv-conditional.patch
new file mode 100644
index 0000000000..542b69dd52
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0017-i915-Make-use-of-sarea_priv-conditional.patch
@@ -0,0 +1,147 @@
1commit 69749cf99189a8a78de201ac24990c91ee111469
2Author: Kristian Høgsberg <krh@redhat.com>
3Date: Wed Aug 20 11:20:13 2008 -0400
4
5 i915: Make use of sarea_priv conditional.
6
7 We fail ioctls that depend on the sarea_priv with EINVAL.
8
9 Signed-off-by: Kristian Høgsberg <krh@redhat.com>
10 Signed-off-by: Eric Anholt <eric@anholt.net>
11
12diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
13index 25f59c1..dbd3f49 100644
14--- a/drivers/gpu/drm/i915/i915_dma.c
15+++ b/drivers/gpu/drm/i915/i915_dma.c
16@@ -55,7 +55,8 @@ int i915_wait_ring(struct drm_device * dev, int n, const char *caller)
17 if (ring->space >= n)
18 return 0;
19
20- dev_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT;
21+ if (dev_priv->sarea_priv)
22+ dev_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT;
23
24 if (ring->head != last_head)
25 i = 0;
26@@ -128,7 +129,7 @@ void i915_kernel_lost_context(struct drm_device * dev)
27 if (ring->space < 0)
28 ring->space += ring->Size;
29
30- if (ring->head == ring->tail)
31+ if (ring->head == ring->tail && dev_priv->sarea_priv)
32 dev_priv->sarea_priv->perf_boxes |= I915_BOX_RING_EMPTY;
33 }
34
35@@ -433,10 +434,11 @@ static void i915_emit_breadcrumb(struct drm_device *dev)
36 drm_i915_private_t *dev_priv = dev->dev_private;
37 RING_LOCALS;
38
39- dev_priv->sarea_priv->last_enqueue = ++dev_priv->counter;
40-
41+ dev_priv->counter++;
42 if (dev_priv->counter > 0x7FFFFFFFUL)
43- dev_priv->sarea_priv->last_enqueue = dev_priv->counter = 1;
44+ dev_priv->counter = 0;
45+ if (dev_priv->sarea_priv)
46+ dev_priv->sarea_priv->last_enqueue = dev_priv->counter;
47
48 BEGIN_LP_RING(4);
49 OUT_RING(MI_STORE_DWORD_INDEX);
50@@ -534,6 +536,9 @@ static int i915_dispatch_flip(struct drm_device * dev)
51 drm_i915_private_t *dev_priv = dev->dev_private;
52 RING_LOCALS;
53
54+ if (!dev_priv->sarea_priv)
55+ return -EINVAL;
56+
57 DRM_DEBUG("%s: page=%d pfCurrentPage=%d\n",
58 __FUNCTION__,
59 dev_priv->current_page,
60@@ -628,7 +633,8 @@ static int i915_batchbuffer(struct drm_device *dev, void *data,
61 ret = i915_dispatch_batchbuffer(dev, batch);
62 mutex_unlock(&dev->struct_mutex);
63
64- sarea_priv->last_dispatch = (int)hw_status[5];
65+ if (sarea_priv)
66+ sarea_priv->last_dispatch = (int)hw_status[5];
67 return ret;
68 }
69
70@@ -663,7 +669,8 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data,
71 return ret;
72 }
73
74- sarea_priv->last_dispatch = (int)hw_status[5];
75+ if (sarea_priv)
76+ sarea_priv->last_dispatch = (int)hw_status[5];
77 return 0;
78 }
79
80diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
81index d04c526..ef03a59 100644
82--- a/drivers/gpu/drm/i915/i915_irq.c
83+++ b/drivers/gpu/drm/i915/i915_irq.c
84@@ -427,7 +427,9 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
85 I915_WRITE(IMR, dev_priv->irq_mask_reg);
86 (void) I915_READ(IIR); /* Flush posted writes */
87
88- dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
89+ if (dev_priv->sarea_priv)
90+ dev_priv->sarea_priv->last_dispatch =
91+ READ_BREADCRUMB(dev_priv);
92
93 if (iir & I915_USER_INTERRUPT) {
94 dev_priv->mm.irq_gem_seqno = i915_get_gem_seqno(dev);
95@@ -456,10 +458,11 @@ static int i915_emit_irq(struct drm_device * dev)
96
97 DRM_DEBUG("\n");
98
99- dev_priv->sarea_priv->last_enqueue = ++dev_priv->counter;
100-
101+ dev_priv->counter++;
102 if (dev_priv->counter > 0x7FFFFFFFUL)
103- dev_priv->sarea_priv->last_enqueue = dev_priv->counter = 1;
104+ dev_priv->counter = 1;
105+ if (dev_priv->sarea_priv)
106+ dev_priv->sarea_priv->last_enqueue = dev_priv->counter;
107
108 BEGIN_LP_RING(6);
109 OUT_RING(MI_STORE_DWORD_INDEX);
110@@ -503,11 +506,15 @@ static int i915_wait_irq(struct drm_device * dev, int irq_nr)
111 READ_BREADCRUMB(dev_priv));
112
113 if (READ_BREADCRUMB(dev_priv) >= irq_nr) {
114- dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
115+ if (dev_priv->sarea_priv) {
116+ dev_priv->sarea_priv->last_dispatch =
117+ READ_BREADCRUMB(dev_priv);
118+ }
119 return 0;
120 }
121
122- dev_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT;
123+ if (dev_priv->sarea_priv)
124+ dev_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT;
125
126 i915_user_irq_get(dev);
127 DRM_WAIT_ON(ret, dev_priv->irq_queue, 3 * DRM_HZ,
128@@ -519,7 +526,9 @@ static int i915_wait_irq(struct drm_device * dev, int irq_nr)
129 READ_BREADCRUMB(dev_priv), (int)dev_priv->counter);
130 }
131
132- dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
133+ if (dev_priv->sarea_priv)
134+ dev_priv->sarea_priv->last_dispatch =
135+ READ_BREADCRUMB(dev_priv);
136
137 return ret;
138 }
139@@ -682,7 +691,7 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
140 struct list_head *list;
141 int ret;
142
143- if (!dev_priv) {
144+ if (!dev_priv || !dev_priv->sarea_priv) {
145 DRM_ERROR("%s called with no initialization\n", __func__);
146 return -EINVAL;
147 }
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0018-i915-gem-install-and-uninstall-irq-handler-in-enter.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0018-i915-gem-install-and-uninstall-irq-handler-in-enter.patch
new file mode 100644
index 0000000000..3593fa5826
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0018-i915-gem-install-and-uninstall-irq-handler-in-enter.patch
@@ -0,0 +1,44 @@
1commit 7ad6d5861b04bbb2cdc36d1dcf8989e16f86e659
2Author: Kristian Høgsberg <krh@redhat.com>
3Date: Wed Aug 20 11:04:27 2008 -0400
4
5 i915 gem: install and uninstall irq handler in entervt and leavevt ioctls.
6
7 Signed-off-by: Kristian Høgsberg <krh@redhat.com>
8 Signed-off-by: Eric Anholt <eric@anholt.net>
9
10diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
11index bb6e5a3..5fe5034 100644
12--- a/drivers/gpu/drm/i915/i915_gem.c
13+++ b/drivers/gpu/drm/i915/i915_gem.c
14@@ -2443,6 +2443,9 @@ i915_gem_entervt_ioctl(struct drm_device *dev, void *data,
15 BUG_ON(!list_empty(&dev_priv->mm.request_list));
16 dev_priv->mm.suspended = 0;
17 mutex_unlock(&dev->struct_mutex);
18+
19+ drm_irq_install(dev);
20+
21 return 0;
22 }
23
24@@ -2458,6 +2461,8 @@ i915_gem_leavevt_ioctl(struct drm_device *dev, void *data,
25 i915_gem_cleanup_ringbuffer(dev);
26 mutex_unlock(&dev->struct_mutex);
27
28+ drm_irq_uninstall(dev);
29+
30 return 0;
31 }
32
33diff --git a/include/drm/drmP.h b/include/drm/drmP.h
34index 1469a1b..51ee72c 100644
35--- a/include/drm/drmP.h
36+++ b/include/drm/drmP.h
37@@ -1134,6 +1134,7 @@ extern void drm_core_reclaim_buffers(struct drm_device *dev,
38 extern int drm_control(struct drm_device *dev, void *data,
39 struct drm_file *file_priv);
40 extern irqreturn_t drm_irq_handler(DRM_IRQ_ARGS);
41+extern int drm_irq_install(struct drm_device *dev);
42 extern int drm_irq_uninstall(struct drm_device *dev);
43 extern void drm_driver_irq_preinstall(struct drm_device *dev);
44 extern void drm_driver_irq_postinstall(struct drm_device *dev);
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0019-DRM-Return-EBADF-on-bad-object-in-flink-and-retur.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0019-DRM-Return-EBADF-on-bad-object-in-flink-and-retur.patch
new file mode 100644
index 0000000000..6de4514e28
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0019-DRM-Return-EBADF-on-bad-object-in-flink-and-retur.patch
@@ -0,0 +1,32 @@
1commit c3de45b0488762a9161e9b9e8bf419f63c100c47
2Author: Eric Anholt <eric@anholt.net>
3Date: Tue Sep 9 11:40:34 2008 -0700
4
5 DRM: Return -EBADF on bad object in flink, and return curent name if it exists.
6
7 Signed-off-by: Eric Anholt <eric@anholt.net>
8
9diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
10index 434155b..ccd1afd 100644
11--- a/drivers/gpu/drm/drm_gem.c
12+++ b/drivers/gpu/drm/drm_gem.c
13@@ -251,7 +251,7 @@ drm_gem_flink_ioctl(struct drm_device *dev, void *data,
14
15 obj = drm_gem_object_lookup(dev, file_priv, args->handle);
16 if (obj == NULL)
17- return -EINVAL;
18+ return -EBADF;
19
20 again:
21 if (idr_pre_get(&dev->object_name_idr, GFP_KERNEL) == 0)
22@@ -259,8 +259,9 @@ again:
23
24 spin_lock(&dev->object_name_lock);
25 if (obj->name) {
26+ args->name = obj->name;
27 spin_unlock(&dev->object_name_lock);
28- return -EEXIST;
29+ return 0;
30 }
31 ret = idr_get_new_above(&dev->object_name_idr, obj, 1,
32 &obj->name);
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0020-drm-Avoid-oops-in-GEM-execbuffers-with-bad-argument.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0020-drm-Avoid-oops-in-GEM-execbuffers-with-bad-argument.patch
new file mode 100644
index 0000000000..7080907cde
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0020-drm-Avoid-oops-in-GEM-execbuffers-with-bad-argument.patch
@@ -0,0 +1,23 @@
1commit 880db7a8dbed226d638b3a48aa1a3996f8624911
2Author: Eric Anholt <eric@anholt.net>
3Date: Wed Sep 10 14:22:49 2008 -0700
4
5 drm: Avoid oops in GEM execbuffers with bad arguments.
6
7 Signed-off-by: Eric Anholt <eric@anholt.net>
8
9diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
10index 5fe5034..29d9d21 100644
11--- a/drivers/gpu/drm/i915/i915_gem.c
12+++ b/drivers/gpu/drm/i915/i915_gem.c
13@@ -1763,6 +1763,10 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
14 (int) args->buffers_ptr, args->buffer_count, args->batch_len);
15 #endif
16
17+ if (args->buffer_count < 1) {
18+ DRM_ERROR("execbuf with %d buffers\n", args->buffer_count);
19+ return -EINVAL;
20+ }
21 /* Copy in the exec list from userland */
22 exec_list = drm_calloc(sizeof(*exec_list), args->buffer_count,
23 DRM_MEM_DRIVER);
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0021-drm-G33-class-hardware-has-a-newer-965-style-MCH-n.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0021-drm-G33-class-hardware-has-a-newer-965-style-MCH-n.patch
new file mode 100644
index 0000000000..f5481d7d85
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0021-drm-G33-class-hardware-has-a-newer-965-style-MCH-n.patch
@@ -0,0 +1,23 @@
1commit 930469634910fa87c21f0a7423c98b270d35d8c6
2Author: Eric Anholt <eric@anholt.net>
3Date: Mon Sep 15 13:13:34 2008 -0700
4
5 drm: G33-class hardware has a newer 965-style MCH (no DCC register).
6
7 Fixes bad software fallback rendering in Mesa in dual-channel configurations.
8
9 d9a2470012588dc5313a5ac8bb2f03575af00e99
10
11diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c
12index 0c1b3a0..6b3f1e4 100644
13--- a/drivers/gpu/drm/i915/i915_gem_tiling.c
14+++ b/drivers/gpu/drm/i915/i915_gem_tiling.c
15@@ -96,7 +96,7 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev)
16 */
17 swizzle_x = I915_BIT_6_SWIZZLE_NONE;
18 swizzle_y = I915_BIT_6_SWIZZLE_NONE;
19- } else if (!IS_I965G(dev) || IS_I965GM(dev)) {
20+ } else if ((!IS_I965G(dev) && !IS_G33(dev)) || IS_I965GM(dev)) {
21 uint32_t dcc;
22
23 /* On 915-945 and GM965, channel interleave by the CPU is
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0022-drm-use-ioremap_wc-in-i915-instead-of-ioremap.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0022-drm-use-ioremap_wc-in-i915-instead-of-ioremap.patch
new file mode 100644
index 0000000000..8e6cbe95a4
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0022-drm-use-ioremap_wc-in-i915-instead-of-ioremap.patch
@@ -0,0 +1,58 @@
1commit d9f2382adde582f8792ad96e9570716bcbea21a0
2Author: Eric Anholt <eric@anholt.net>
3Date: Tue Sep 23 14:50:57 2008 -0700
4
5 drm: Use ioremap_wc in i915_driver instead of ioremap, since we always want WC.
6
7 Fixes failure to map the ringbuffer when PAT tells us we don't get to do
8 uncached on something that's already mapped WC, or something along those lines.
9
10 Signed-off-by: Eric Anholt <eric@anholt.net>
11
12diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
13index 29d9d21..6ecfd10 100644
14--- a/drivers/gpu/drm/i915/i915_gem.c
15+++ b/drivers/gpu/drm/i915/i915_gem.c
16@@ -233,7 +233,7 @@ i915_gem_gtt_pwrite(struct drm_device *dev, struct drm_gem_object *obj,
17 if (unwritten)
18 #endif /* CONFIG_HIGHMEM */
19 {
20- vaddr = ioremap(pfn << PAGE_SHIFT, PAGE_SIZE);
21+ vaddr = ioremap_wc(pfn << PAGE_SHIFT, PAGE_SIZE);
22 #if WATCH_PWRITE
23 DRM_INFO("pwrite slow i %d o %d l %d "
24 "pfn %ld vaddr %p\n",
25@@ -1612,9 +1612,10 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj,
26 if (reloc_page != NULL)
27 iounmap(reloc_page);
28
29- reloc_page = ioremap(dev->agp->base +
30- (reloc_offset & ~(PAGE_SIZE - 1)),
31- PAGE_SIZE);
32+ reloc_page = ioremap_wc(dev->agp->base +
33+ (reloc_offset &
34+ ~(PAGE_SIZE - 1)),
35+ PAGE_SIZE);
36 last_reloc_offset = reloc_offset;
37 if (reloc_page == NULL) {
38 drm_gem_object_unreference(target_obj);
39@@ -2318,7 +2319,9 @@ i915_gem_init_hws(struct drm_device *dev)
40 dev_priv->hws_map.flags = 0;
41 dev_priv->hws_map.mtrr = 0;
42
43- drm_core_ioremap(&dev_priv->hws_map, dev);
44+ /* Ioremapping here is the wrong thing to do. We want cached access.
45+ */
46+ drm_core_ioremap_wc(&dev_priv->hws_map, dev);
47 if (dev_priv->hws_map.handle == NULL) {
48 DRM_ERROR("Failed to map status page.\n");
49 memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map));
50@@ -2369,7 +2372,7 @@ i915_gem_init_ringbuffer(struct drm_device *dev)
51 dev_priv->ring.map.flags = 0;
52 dev_priv->ring.map.mtrr = 0;
53
54- drm_core_ioremap(&dev_priv->ring.map, dev);
55+ drm_core_ioremap_wc(&dev_priv->ring.map, dev);
56 if (dev_priv->ring.map.handle == NULL) {
57 DRM_ERROR("Failed to map ringbuffer.\n");
58 memset(&dev_priv->ring, 0, sizeof(dev_priv->ring));
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0023-drm-clean-up-many-sparse-warnings-in-i915.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0023-drm-clean-up-many-sparse-warnings-in-i915.patch
new file mode 100644
index 0000000000..236b161587
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0023-drm-clean-up-many-sparse-warnings-in-i915.patch
@@ -0,0 +1,192 @@
1commit 034994cfffbb2371b720e3f49378031ebc12645e
2Author: Eric Anholt <eric@anholt.net>
3Date: Thu Oct 2 12:24:47 2008 -0700
4
5 drm: Clean up many sparse warnings in i915.
6
7 Signed-off-by: Eric Anholt <eric@anholt.net>
8
9diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
10index dbd3f49..814cc12 100644
11--- a/drivers/gpu/drm/i915/i915_dma.c
12+++ b/drivers/gpu/drm/i915/i915_dma.c
13@@ -76,7 +76,7 @@ int i915_wait_ring(struct drm_device * dev, int n, const char *caller)
14 * Sets up the hardware status page for devices that need a physical address
15 * in the register.
16 */
17-int i915_init_phys_hws(struct drm_device *dev)
18+static int i915_init_phys_hws(struct drm_device *dev)
19 {
20 drm_i915_private_t *dev_priv = dev->dev_private;
21 /* Program Hardware Status Page */
22@@ -101,7 +101,7 @@ int i915_init_phys_hws(struct drm_device *dev)
23 * Frees the hardware status page, whether it's a physical address or a virtual
24 * address set up by the X Server.
25 */
26-void i915_free_hws(struct drm_device *dev)
27+static void i915_free_hws(struct drm_device *dev)
28 {
29 drm_i915_private_t *dev_priv = dev->dev_private;
30 if (dev_priv->status_page_dmah) {
31@@ -145,8 +145,8 @@ static int i915_dma_cleanup(struct drm_device * dev)
32
33 if (dev_priv->ring.virtual_start) {
34 drm_core_ioremapfree(&dev_priv->ring.map, dev);
35- dev_priv->ring.virtual_start = 0;
36- dev_priv->ring.map.handle = 0;
37+ dev_priv->ring.virtual_start = NULL;
38+ dev_priv->ring.map.handle = NULL;
39 dev_priv->ring.map.size = 0;
40 }
41
42@@ -827,9 +827,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
43 base = drm_get_resource_start(dev, mmio_bar);
44 size = drm_get_resource_len(dev, mmio_bar);
45
46- ret = drm_addmap(dev, base, size, _DRM_REGISTERS,
47- _DRM_KERNEL | _DRM_DRIVER,
48- &dev_priv->mmio_map);
49+ dev_priv->regs = ioremap(base, size);
50
51 i915_gem_load(dev);
52
53@@ -867,8 +865,8 @@ int i915_driver_unload(struct drm_device *dev)
54
55 i915_free_hws(dev);
56
57- if (dev_priv->mmio_map)
58- drm_rmmap(dev, dev_priv->mmio_map);
59+ if (dev_priv->regs != NULL)
60+ iounmap(dev_priv->regs);
61
62 intel_opregion_free(dev);
63
64diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
65index 8547f0a..b184d54 100644
66--- a/drivers/gpu/drm/i915/i915_drv.h
67+++ b/drivers/gpu/drm/i915/i915_drv.h
68@@ -110,8 +110,8 @@ struct intel_opregion {
69 typedef struct drm_i915_private {
70 struct drm_device *dev;
71
72+ void __iomem *regs;
73 drm_local_map_t *sarea;
74- drm_local_map_t *mmio_map;
75
76 drm_i915_sarea_t *sarea_priv;
77 drm_i915_ring_buffer_t ring;
78@@ -553,12 +553,12 @@ extern void opregion_enable_asle(struct drm_device *dev);
79 LOCK_TEST_WITH_RETURN(dev, file_priv); \
80 } while (0)
81
82-#define I915_READ(reg) DRM_READ32(dev_priv->mmio_map, (reg))
83-#define I915_WRITE(reg,val) DRM_WRITE32(dev_priv->mmio_map, (reg), (val))
84-#define I915_READ16(reg) DRM_READ16(dev_priv->mmio_map, (reg))
85-#define I915_WRITE16(reg,val) DRM_WRITE16(dev_priv->mmio_map, (reg), (val))
86-#define I915_READ8(reg) DRM_READ8(dev_priv->mmio_map, (reg))
87-#define I915_WRITE8(reg,val) DRM_WRITE8(dev_priv->mmio_map, (reg), (val))
88+#define I915_READ(reg) readl(dev_priv->regs + (reg))
89+#define I915_WRITE(reg,val) writel(val, dev_priv->regs + (reg))
90+#define I915_READ16(reg) readw(dev_priv->regs + (reg))
91+#define I915_WRITE16(reg,val) writel(val, dev_priv->regs + (reg))
92+#define I915_READ8(reg) readb(dev_priv->regs + (reg))
93+#define I915_WRITE8(reg,val) writeb(val, dev_priv->regs + (reg))
94
95 #define I915_VERBOSE 0
96
97diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
98index 6ecfd10..6a89449 100644
99--- a/drivers/gpu/drm/i915/i915_gem.c
100+++ b/drivers/gpu/drm/i915/i915_gem.c
101@@ -176,7 +176,8 @@ i915_gem_gtt_pwrite(struct drm_device *dev, struct drm_gem_object *obj,
102 ssize_t remain;
103 loff_t offset;
104 char __user *user_data;
105- char *vaddr;
106+ char __iomem *vaddr;
107+ char *vaddr_atomic;
108 int i, o, l;
109 int ret = 0;
110 unsigned long pfn;
111@@ -219,16 +220,20 @@ i915_gem_gtt_pwrite(struct drm_device *dev, struct drm_gem_object *obj,
112 pfn = (dev->agp->base >> PAGE_SHIFT) + i;
113
114 #ifdef CONFIG_HIGHMEM
115- /* kmap_atomic can't map IO pages on non-HIGHMEM kernels
116+ /* This is a workaround for the low performance of iounmap
117+ * (approximate 10% cpu cost on normal 3D workloads).
118+ * kmap_atomic on HIGHMEM kernels happens to let us map card
119+ * memory without taking IPIs. When the vmap rework lands
120+ * we should be able to dump this hack.
121 */
122- vaddr = kmap_atomic_pfn(pfn, KM_USER0);
123+ vaddr_atomic = kmap_atomic_pfn(pfn, KM_USER0);
124 #if WATCH_PWRITE
125 DRM_INFO("pwrite i %d o %d l %d pfn %ld vaddr %p\n",
126- i, o, l, pfn, vaddr);
127+ i, o, l, pfn, vaddr_atomic);
128 #endif
129- unwritten = __copy_from_user_inatomic_nocache(vaddr + o,
130+ unwritten = __copy_from_user_inatomic_nocache(vaddr_atomic + o,
131 user_data, l);
132- kunmap_atomic(vaddr, KM_USER0);
133+ kunmap_atomic(vaddr_atomic, KM_USER0);
134
135 if (unwritten)
136 #endif /* CONFIG_HIGHMEM */
137@@ -271,7 +276,7 @@ fail:
138 return ret;
139 }
140
141-int
142+static int
143 i915_gem_shmem_pwrite(struct drm_device *dev, struct drm_gem_object *obj,
144 struct drm_i915_gem_pwrite *args,
145 struct drm_file *file_priv)
146@@ -587,7 +592,7 @@ i915_add_request(struct drm_device *dev, uint32_t flush_domains)
147 * Ensures that all commands in the ring are finished
148 * before signalling the CPU
149 */
150-uint32_t
151+static uint32_t
152 i915_retire_commands(struct drm_device *dev)
153 {
154 drm_i915_private_t *dev_priv = dev->dev_private;
155@@ -734,7 +739,7 @@ i915_gem_retire_work_handler(struct work_struct *work)
156 * Waits for a sequence number to be signaled, and cleans up the
157 * request and object lists appropriately for that event.
158 */
159-int
160+static int
161 i915_wait_request(struct drm_device *dev, uint32_t seqno)
162 {
163 drm_i915_private_t *dev_priv = dev->dev_private;
164@@ -1483,7 +1488,7 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj,
165 struct drm_i915_gem_object *obj_priv = obj->driver_private;
166 int i, ret;
167 uint32_t last_reloc_offset = -1;
168- void *reloc_page = NULL;
169+ void __iomem *reloc_page = NULL;
170
171 /* Choose the GTT offset for our buffer and put it there. */
172 ret = i915_gem_object_pin(obj, (uint32_t) entry->alignment);
173@@ -1500,8 +1505,8 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj,
174 for (i = 0; i < entry->relocation_count; i++) {
175 struct drm_gem_object *target_obj;
176 struct drm_i915_gem_object *target_obj_priv;
177- uint32_t reloc_val, reloc_offset, *reloc_entry;
178- int ret;
179+ uint32_t reloc_val, reloc_offset;
180+ uint32_t __iomem *reloc_entry;
181
182 ret = copy_from_user(&reloc, relocs + i, sizeof(reloc));
183 if (ret != 0) {
184@@ -1624,7 +1629,7 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj,
185 }
186 }
187
188- reloc_entry = (uint32_t *)((char *)reloc_page +
189+ reloc_entry = (uint32_t __iomem *)(reloc_page +
190 (reloc_offset & (PAGE_SIZE - 1)));
191 reloc_val = target_obj_priv->gtt_offset + reloc.delta;
192
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0024-fastboot-create-a-asynchronous-initlevel.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0024-fastboot-create-a-asynchronous-initlevel.patch
new file mode 100644
index 0000000000..7c19053b0e
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0024-fastboot-create-a-asynchronous-initlevel.patch
@@ -0,0 +1,136 @@
1From ac9103dd8e4dc65c110d6cba9a3380c6c617ffa7 Mon Sep 17 00:00:00 2001
2From: Arjan van de Ven <arjan@linux.intel.com>
3Date: Fri, 18 Jul 2008 15:16:08 -0700
4Subject: [PATCH] fastboot: create a "asynchronous" initlevel
5
6This patch creates an asynchronous initlevel (6a) which is at the same
7level as the normal device initcalls, but with the difference that they
8are run asynchronous from all the other initcalls. The purpose of this
9*selective* level is that we can move long waiting inits that are not
10boot-critical to this level one at a time.
11
12To keep things not totally insane, the asynchronous initcalls are async
13to the other initcalls, but are still ordered to themselves; think of it
14as "bottom-half-not-softirq". This has the benefit that async drivers
15still have stable device ordering between them.
16
17Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
18Signed-off-by: Ingo Molnar <mingo@elte.hu>
19---
20 include/asm-generic/vmlinux.lds.h | 3 +++
21 include/linux/init.h | 6 ++++++
22 init/main.c | 36 +++++++++++++++++++++++++++++++++---
23 3 files changed, 42 insertions(+), 3 deletions(-)
24
25diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
26index 729f6b0..39c1afc 100644
27--- a/include/asm-generic/vmlinux.lds.h
28+++ b/include/asm-generic/vmlinux.lds.h
29@@ -372,6 +372,9 @@
30 *(.initcall5.init) \
31 *(.initcall5s.init) \
32 *(.initcallrootfs.init) \
33+ __async_initcall_start = .; \
34+ *(.initcall6a.init) \
35+ __async_initcall_end = .; \
36 *(.initcall6.init) \
37 *(.initcall6s.init) \
38 *(.initcall7.init) \
39diff --git a/include/linux/init.h b/include/linux/init.h
40index 21d658c..75db909 100644
41--- a/include/linux/init.h
42+++ b/include/linux/init.h
43@@ -197,11 +197,13 @@
44 #define fs_initcall_sync(fn) __define_initcall("5s",fn,5s)
45 #define rootfs_initcall(fn) __define_initcall("rootfs",fn,rootfs)
46 #define device_initcall(fn) __define_initcall("6",fn,6)
47+#define device_initcall_async(fn) __define_initcall("6a", fn, 6a)
48 #define device_initcall_sync(fn) __define_initcall("6s",fn,6s)
49 #define late_initcall(fn) __define_initcall("7",fn,7)
50 #define late_initcall_sync(fn) __define_initcall("7s",fn,7s)
51
52 #define __initcall(fn) device_initcall(fn)
53+#define __initcall_async(fn) device_initcall_async(fn)
54
55 #define __exitcall(fn) \
56 static exitcall_t __exitcall_##fn __exit_call = fn
57@@ -257,6 +259,7 @@
58 * be one per module.
59 */
60 #define module_init(x) __initcall(x);
61+#define module_init_async(x) __initcall_async(x);
62
63 /**
64 * module_exit() - driver exit entry point
65@@ -279,10 +282,13 @@
66 #define subsys_initcall(fn) module_init(fn)
67 #define fs_initcall(fn) module_init(fn)
68 #define device_initcall(fn) module_init(fn)
69+#define device_initcall_async(fn) module_init(fn)
70 #define late_initcall(fn) module_init(fn)
71
72 #define security_initcall(fn) module_init(fn)
73
74+#define module_init_async(fn) module_init(fn)
75+
76 /* Each module must use one module_init(). */
77 #define module_init(initfn) \
78 static inline initcall_t __inittest(void) \
79diff --git a/init/main.c b/init/main.c
80index edeace0..6961de2 100644
81--- a/init/main.c
82+++ b/init/main.c
83@@ -746,18 +746,47 @@
84
85
86 extern initcall_t __initcall_start[], __initcall_end[], __early_initcall_end[];
87+extern initcall_t __async_initcall_start[], __async_initcall_end[];
88
89-static void __init do_initcalls(void)
90+static void __init do_async_initcalls(struct work_struct *dummy)
91 {
92 initcall_t *call;
93
94- for (call = __early_initcall_end; call < __initcall_end; call++)
95+ for (call = __async_initcall_start; call < __async_initcall_end; call++)
96 do_one_initcall(*call);
97+}
98+
99+static struct workqueue_struct *async_init_wq;
100+
101+static void __init do_initcalls(void)
102+{
103+ initcall_t *call;
104+ static DECLARE_WORK(async_work, do_async_initcalls);
105+ int phase = 0; /* 0 = levels 0 - 6, 1 = level 6a, 2 = after level 6a */
106+
107+ async_init_wq = create_singlethread_workqueue("kasyncinit");
108+
109+ for (call = __early_initcall_end; call < __initcall_end; call++) {
110+ if (phase == 0 && call >= __async_initcall_start) {
111+ phase = 1;
112+ queue_work(async_init_wq, &async_work);
113+ }
114+ if (phase == 1 && call >= __async_initcall_end)
115+ phase = 2;
116+ if (phase != 1)
117+ do_one_initcall(*call);
118+ }
119
120- /* Make sure there is no pending stuff from the initcall sequence */
121+ /*
122+ * Make sure there is no pending stuff from the initcall sequence,
123+ * including the async initcalls
124+ */
125 flush_scheduled_work();
126+ flush_workqueue(async_init_wq);
127+ destroy_workqueue(async_init_wq);
128 }
129
130+
131 /*
132 * Ok, the machine is now initialized. None of the devices
133 * have been touched yet, but the CPU subsystem is up and
134--
1351.5.4.3
136
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0025-fastboot-turn-the-USB-hostcontroller-initcalls-into.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0025-fastboot-turn-the-USB-hostcontroller-initcalls-into.patch
new file mode 100644
index 0000000000..75d4151b3b
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0025-fastboot-turn-the-USB-hostcontroller-initcalls-into.patch
@@ -0,0 +1,62 @@
1From d1a26186ee222329a797bb0b2c8e2b5bc7d94d42 Mon Sep 17 00:00:00 2001
2From: Arjan van de Ven <arjan@linux.intel.com>
3Date: Fri, 18 Jul 2008 15:16:53 -0700
4Subject: [PATCH] fastboot: turn the USB hostcontroller initcalls into async initcalls
5
6the USB host controller init calls take a long time, mostly due to a
7"minimally 100 msec" delay *per port* during initialization.
8These are prime candidates for going in parallel to everything else.
9
10The USB device ordering is not affected by this due to the
11serialized-within-eachother property of async initcalls.
12
13Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
14Signed-off-by: Ingo Molnar <mingo@elte.hu>
15---
16 drivers/usb/host/ehci-hcd.c | 2 +-
17 drivers/usb/host/ohci-hcd.c | 2 +-
18 drivers/usb/host/uhci-hcd.c | 2 +-
19 3 files changed, 3 insertions(+), 3 deletions(-)
20
21diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
22index 369a8a5..8f84b17 100644
23--- a/drivers/usb/host/ehci-hcd.c
24+++ b/drivers/usb/host/ehci-hcd.c
25@@ -1101,7 +1101,7 @@ clean0:
26 #endif
27 return retval;
28 }
29-module_init(ehci_hcd_init);
30+module_init_async(ehci_hcd_init);
31
32 static void __exit ehci_hcd_cleanup(void)
33 {
34diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
35index a8160d6..e060ed1 100644
36--- a/drivers/usb/host/ohci-hcd.c
37+++ b/drivers/usb/host/ohci-hcd.c
38@@ -1165,7 +1165,7 @@ static int __init ohci_hcd_mod_init(void)
39
40 return retval;
41 }
42-module_init(ohci_hcd_mod_init);
43+module_init_async(ohci_hcd_mod_init);
44
45 static void __exit ohci_hcd_mod_exit(void)
46 {
47diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
48index 3a7bfe7..f2a05ac 100644
49--- a/drivers/usb/host/uhci-hcd.c
50+++ b/drivers/usb/host/uhci-hcd.c
51@@ -999,7 +999,7 @@ static void __exit uhci_hcd_cleanup(void)
52 kfree(errbuf);
53 }
54
55-module_init(uhci_hcd_init);
56+module_init_async(uhci_hcd_init);
57 module_exit(uhci_hcd_cleanup);
58
59 MODULE_AUTHOR(DRIVER_AUTHOR);
60--
611.5.4.3
62
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0026-fastboot-convert-a-few-non-critical-ACPI-drivers-to.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0026-fastboot-convert-a-few-non-critical-ACPI-drivers-to.patch
new file mode 100644
index 0000000000..efd8ca9c9c
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0026-fastboot-convert-a-few-non-critical-ACPI-drivers-to.patch
@@ -0,0 +1,54 @@
1From 60ddc2e5c44b4b9f5fcb440065469eacbeabf5eb Mon Sep 17 00:00:00 2001
2From: Arjan van de Ven <arjan@linux.intel.com>
3Date: Fri, 18 Jul 2008 15:17:35 -0700
4Subject: [PATCH] fastboot: convert a few non-critical ACPI drivers to async initcalls
5
6This patch converts a few non-critical ACPI drivers to async initcalls;
7these initcalls (battery, button and thermal) tend to take quite a bit of
8time (100's of milliseconds) due to the hardware they need to talk to,
9but are otherwise clearly non-essential for the boot process.
10
11Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
12Signed-off-by: Ingo Molnar <mingo@elte.hu>
13---
14 drivers/acpi/battery.c | 2 +-
15 drivers/acpi/button.c | 2 +-
16 drivers/acpi/thermal.c | 2 +-
17 3 files changed, 3 insertions(+), 3 deletions(-)
18
19diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
20index b1c723f..d5d30ca 100644
21--- a/drivers/acpi/battery.c
22+++ b/drivers/acpi/battery.c
23@@ -904,5 +904,5 @@ static void __exit acpi_battery_exit(void)
24 #endif
25 }
26
27-module_init(acpi_battery_init);
28+module_init_async(acpi_battery_init);
29 module_exit(acpi_battery_exit);
30diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
31index 1dfec41..46b3805 100644
32--- a/drivers/acpi/button.c
33+++ b/drivers/acpi/button.c
34@@ -545,5 +545,5 @@ static void __exit acpi_button_exit(void)
35 remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir);
36 }
37
38-module_init(acpi_button_init);
39+module_init_async(acpi_button_init);
40 module_exit(acpi_button_exit);
41diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
42index 84c795f..1f529af 100644
43--- a/drivers/acpi/thermal.c
44+++ b/drivers/acpi/thermal.c
45@@ -1833,5 +1833,5 @@ static void __exit acpi_thermal_exit(void)
46 return;
47 }
48
49-module_init(acpi_thermal_init);
50+module_init_async(acpi_thermal_init);
51 module_exit(acpi_thermal_exit);
52--
531.5.4.3
54
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0027-fastboot-hold-the-BKL-over-the-async-init-call-sequ.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0027-fastboot-hold-the-BKL-over-the-async-init-call-sequ.patch
new file mode 100644
index 0000000000..129823b6ce
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0027-fastboot-hold-the-BKL-over-the-async-init-call-sequ.patch
@@ -0,0 +1,40 @@
1From 3e6558b693dd1e69e3177bc248977f067a769f14 Mon Sep 17 00:00:00 2001
2From: Arjan van de Ven <arjan@linux.intel.com>
3Date: Sun, 20 Jul 2008 08:59:24 -0700
4Subject: [PATCH] fastboot: hold the BKL over the async init call sequence
5
6Regular init calls are called with the BKL held; make sure
7the async init calls are also called with the BKL held.
8While this reduces parallelism a little, it does provide
9lock-for-lock compatibility. The hit to prallelism isn't too
10bad, most of the init calls are done immediately or actually
11block for their delays.
12
13Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
14Signed-off-by: Ingo Molnar <mingo@elte.hu>
15---
16 init/main.c | 6 ++++++
17 1 files changed, 6 insertions(+), 0 deletions(-)
18
19diff --git a/init/main.c b/init/main.c
20index 6961de2..9e2aee8 100644
21--- a/init/main.c
22+++ b/init/main.c
23@@ -744,8 +744,14 @@ static void __init do_async_initcalls(struct work_struct *dummy)
24 {
25 initcall_t *call;
26
27+ /*
28+ * For compatibility with normal init calls... take the BKL
29+ * not pretty, not desirable, but compatibility first
30+ */
31+ lock_kernel();
32 for (call = __async_initcall_start; call < __async_initcall_end; call++)
33 do_one_initcall(*call);
34+ unlock_kernel();
35 }
36
37 static struct workqueue_struct *async_init_wq;
38--
391.5.4.3
40
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0028-fastboot-sync-the-async-execution-before-late_initc.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0028-fastboot-sync-the-async-execution-before-late_initc.patch
new file mode 100644
index 0000000000..0700fb3189
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0028-fastboot-sync-the-async-execution-before-late_initc.patch
@@ -0,0 +1,95 @@
1From 660625fb93f2fc0e633da9cb71d13d895b385f64 Mon Sep 17 00:00:00 2001
2From: Arjan van de Ven <arjan@linux.intel.com>
3Date: Sun, 20 Jul 2008 09:00:41 -0700
4Subject: [PATCH] fastboot: sync the async execution before late_initcall and move level 6s (sync) first
5
6Rene Herman points out several cases where it's basically needed to have
7all level 6/6a/6s calls done before the level 7 (late_initcall) code
8runs. This patch adds a sync point in the transition from the 6's to the
97's.
10
11Second, this patch makes sure that level 6s (sync) happens before the
12async code starts, and puts a user in driver/pci in this category that
13needs to happen before device init.
14
15Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
16Signed-off-by: Ingo Molnar <mingo@elte.hu>
17---
18 drivers/pci/pci.c | 2 +-
19 include/asm-generic/vmlinux.lds.h | 3 ++-
20 init/main.c | 14 +++++++++++++-
21 3 files changed, 16 insertions(+), 3 deletions(-)
22
23diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
24index 44a46c9..d75295d 100644
25--- a/drivers/pci/pci.c
26+++ b/drivers/pci/pci.c
27@@ -1889,7 +1889,7 @@ static int __devinit pci_setup(char *str)
28 }
29 early_param("pci", pci_setup);
30
31-device_initcall(pci_init);
32+device_initcall_sync(pci_init);
33
34 EXPORT_SYMBOL(pci_reenable_device);
35 EXPORT_SYMBOL(pci_enable_device_io);
36diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
37index 39c1afc..020c641 100644
38--- a/include/asm-generic/vmlinux.lds.h
39+++ b/include/asm-generic/vmlinux.lds.h
40@@ -372,11 +372,12 @@
41 *(.initcall5.init) \
42 *(.initcall5s.init) \
43 *(.initcallrootfs.init) \
44+ *(.initcall6s.init) \
45 __async_initcall_start = .; \
46 *(.initcall6a.init) \
47 __async_initcall_end = .; \
48 *(.initcall6.init) \
49- *(.initcall6s.init) \
50+ __device_initcall_end = .; \
51 *(.initcall7.init) \
52 *(.initcall7s.init)
53
54diff --git a/init/main.c b/init/main.c
55index 9e2aee8..6be1756 100644
56--- a/init/main.c
57+++ b/init/main.c
58@@ -739,6 +739,7 @@ static void __init do_one_initcall(initcall_t fn)
59
60 extern initcall_t __initcall_start[], __initcall_end[];
61 extern initcall_t __async_initcall_start[], __async_initcall_end[];
62+extern initcall_t __device_initcall_end[];
63
64 static void __init do_async_initcalls(struct work_struct *dummy)
65 {
66@@ -762,7 +763,13 @@ static void __init do_initcalls(void)
67 {
68 initcall_t *call;
69 static DECLARE_WORK(async_work, do_async_initcalls);
70- int phase = 0; /* 0 = levels 0 - 6, 1 = level 6a, 2 = after level 6a */
71+ /*
72+ * 0 = levels 0 - 6,
73+ * 1 = level 6a,
74+ * 2 = after level 6a,
75+ * 3 = after level 6
76+ */
77+ int phase = 0;
78
79 async_init_wq = create_singlethread_workqueue("kasyncinit");
80
81@@ -773,6 +780,11 @@ static void __init do_initcalls(void)
82 }
83 if (phase == 1 && call >= __async_initcall_end)
84 phase = 2;
85+ if (phase == 2 && call >= __device_initcall_end) {
86+ phase = 3;
87+ /* make sure all async work is done before level 7 */
88+ flush_workqueue(async_init_wq);
89+ }
90 if (phase != 1)
91 do_one_initcall(*call);
92 }
93--
941.5.4.3
95
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0029-fastboot-make-fastboot-a-config-option.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0029-fastboot-make-fastboot-a-config-option.patch
new file mode 100644
index 0000000000..faf9622091
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0029-fastboot-make-fastboot-a-config-option.patch
@@ -0,0 +1,56 @@
1From 50b6962016b824dfac254b8f36fc6cac301c8a8d Mon Sep 17 00:00:00 2001
2From: Arjan van de Ven <arjan@linux.intel.com>
3Date: Sun, 20 Jul 2008 10:20:49 -0700
4Subject: [PATCH] fastboot: make fastboot a config option
5
6to mitigate the risks of async bootup, make fastboot a configuration
7option...
8
9Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
10Signed-off-by: Ingo Molnar <mingo@elte.hu>
11---
12 init/Kconfig | 11 +++++++++++
13 init/main.c | 4 ++++
14 2 files changed, 15 insertions(+), 0 deletions(-)
15
16diff --git a/init/Kconfig b/init/Kconfig
17index 6199d11..7545c8b 100644
18--- a/init/Kconfig
19+++ b/init/Kconfig
20@@ -524,6 +524,17 @@ config CC_OPTIMIZE_FOR_SIZE
21
22 If unsure, say N.
23
24+config FASTBOOT
25+ bool "Fast boot support"
26+ help
27+ The fastboot option will cause the kernel to try to optimize
28+ for faster boot.
29+
30+ This includes doing some of the device initialization asynchronous
31+ as well as opportunistically trying to mount the root fs early.
32+
33+ If unsure, say N.
34+
35 config SYSCTL
36 bool
37
38diff --git a/init/main.c b/init/main.c
39index 6be1756..bb97add 100644
40--- a/init/main.c
41+++ b/init/main.c
42@@ -776,7 +776,11 @@ static void __init do_initcalls(void)
43 for (call = __initcall_start; call < __initcall_end; call++) {
44 if (phase == 0 && call >= __async_initcall_start) {
45 phase = 1;
46+#ifdef CONFIG_FASTBOOT
47 queue_work(async_init_wq, &async_work);
48+#else
49+ do_async_initcalls(NULL);
50+#endif
51 }
52 if (phase == 1 && call >= __async_initcall_end)
53 phase = 2;
54--
551.5.4.3
56
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0030-fastboot-retry-mounting-the-root-fs-if-we-can-t-fin.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0030-fastboot-retry-mounting-the-root-fs-if-we-can-t-fin.patch
new file mode 100644
index 0000000000..e2c3737935
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0030-fastboot-retry-mounting-the-root-fs-if-we-can-t-fin.patch
@@ -0,0 +1,67 @@
1From db62cd29f9b9142c19c574ca00916f66ff22ed4a Mon Sep 17 00:00:00 2001
2From: Arjan van de Ven <arjan@linux.intel.com>
3Date: Sun, 20 Jul 2008 13:01:28 -0700
4Subject: [PATCH] fastboot: retry mounting the root fs if we can't find init
5
6currently we wait until all device init is done before trying to mount
7the root fs, and to consequently execute init.
8
9In preparation for relaxing the first delay, this patch adds a retry
10attempt in case /sbin/init is not found. Before retrying, the code
11will wait for all device init to complete.
12
13While this patch by itself doesn't gain boot time yet (it needs follow on
14patches), the alternative already is to panic()...
15
16Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
17---
18 init/main.c | 19 +++++++++++++++++++
19 1 files changed, 19 insertions(+), 0 deletions(-)
20
21diff --git a/init/main.c b/init/main.c
22index 3575b84..73785a4 100644
23--- a/init/main.c
24+++ b/init/main.c
25@@ -853,6 +853,7 @@ static void run_init_process(char *init_filename)
26 */
27 static int noinline init_post(void)
28 {
29+ int retry_count = 1;
30 free_initmem();
31 unlock_kernel();
32 mark_rodata_ro();
33@@ -873,6 +874,7 @@ static int noinline init_post(void)
34 ramdisk_execute_command);
35 }
36
37+retry:
38 /*
39 * We try each of these until one succeeds.
40 *
41@@ -885,6 +887,23 @@ static int noinline init_post(void)
42 "defaults...\n", execute_command);
43 }
44 run_init_process("/sbin/init");
45+
46+ if (retry_count > 0) {
47+ retry_count--;
48+ /*
49+ * We haven't found init yet... potentially because the device
50+ * is still being probed. We need to
51+ * - flush keventd and friends
52+ * - wait for the known devices to complete their probing
53+ * - try to mount the root fs again
54+ */
55+ flush_scheduled_work();
56+ while (driver_probe_done() != 0)
57+ msleep(100);
58+ prepare_namespace();
59+ goto retry;
60+ }
61+
62 run_init_process("/etc/init");
63 run_init_process("/bin/init");
64 run_init_process("/bin/sh");
65--
661.5.4.3
67
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0031-fastboot-make-the-raid-autodetect-code-wait-for-all.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0031-fastboot-make-the-raid-autodetect-code-wait-for-all.patch
new file mode 100644
index 0000000000..03b3b82202
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0031-fastboot-make-the-raid-autodetect-code-wait-for-all.patch
@@ -0,0 +1,41 @@
1From b52c36a95ed8026b6925fe8595ebcab6921ae62d Mon Sep 17 00:00:00 2001
2From: Arjan van de Ven <arjan@linux.intel.com>
3Date: Sun, 20 Jul 2008 13:07:09 -0700
4Subject: [PATCH] fastboot: make the raid autodetect code wait for all devices to init
5
6The raid autodetect code really needs to have all devices probed before
7it can detect raid arrays; not doing so would give rather messy situations
8where arrays would get detected as degraded while they shouldn't be etc.
9
10This is in preparation of removing the "wait for everything to init"
11code that makes everyone pay, not just raid users.
12
13Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
14---
15 init/do_mounts_md.c | 7 +++++++
16 1 files changed, 7 insertions(+), 0 deletions(-)
17
18diff --git a/init/do_mounts_md.c b/init/do_mounts_md.c
19index 693d246..c0412a9 100644
20--- a/init/do_mounts_md.c
21+++ b/init/do_mounts_md.c
22@@ -267,9 +267,16 @@ __setup("md=", md_setup);
23 void __init md_run_setup(void)
24 {
25 create_dev("/dev/md0", MKDEV(MD_MAJOR, 0));
26+
27 if (raid_noautodetect)
28 printk(KERN_INFO "md: Skipping autodetection of RAID arrays. (raid=noautodetect)\n");
29 else {
30+ /*
31+ * Since we don't want to detect and use half a raid array, we need to
32+ * wait for the known devices to complete their probing
33+ */
34+ while (driver_probe_done() != 0)
35+ msleep(100);
36 int fd = sys_open("/dev/md0", 0, 0);
37 if (fd >= 0) {
38 sys_ioctl(fd, RAID_AUTORUN, raid_autopart);
39--
401.5.4.3
41
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0032-fastboot-remove-wait-for-all-devices-before-mounti.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0032-fastboot-remove-wait-for-all-devices-before-mounti.patch
new file mode 100644
index 0000000000..4e9be15e1d
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0032-fastboot-remove-wait-for-all-devices-before-mounti.patch
@@ -0,0 +1,44 @@
1From 1b5a2bd0602010398cb473d1b821a9f1c1399caf Mon Sep 17 00:00:00 2001
2From: Arjan van de Ven <arjan@linux.intel.com>
3Date: Sun, 20 Jul 2008 13:12:16 -0700
4Subject: [PATCH] fastboot: remove "wait for all devices before mounting root" delay
5
6In the non-initrd case, we wait for all devices to finish their
7probing before we try to mount the rootfs.
8In practice, this means that we end up waiting 2 extra seconds for
9the PS/2 mouse probing even though the root holding device has been
10ready since a long time.
11
12The previous two patches in this series made the RAID autodetect code
13do it's own "wait for probing to be done" code, and added
14"wait and retry" functionality in case the root device isn't actually
15available.
16
17These two changes should make it safe to remove the delay itself,
18and this patch does this. On my test laptop, this reduces the boot time
19by 2 seconds (kernel time goes from 3.9 to 1.9 seconds).
20
21Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
22---
23 init/do_mounts.c | 2 ++
24 1 files changed, 2 insertions(+), 0 deletions(-)
25
26diff --git a/init/do_mounts.c b/init/do_mounts.c
27index a1de1bf..c984fab 100644
28--- a/init/do_mounts.c
29+++ b/init/do_mounts.c
30@@ -364,9 +364,11 @@ void __init prepare_namespace(void)
31 ssleep(root_delay);
32 }
33
34+#ifndef CONFIG_FASTBOOT
35 /* wait for the known devices to complete their probing */
36 while (driver_probe_done() != 0)
37 msleep(100);
38+#endif
39
40 md_run_setup();
41
42--
431.5.4.3
44
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0033-fastboot-make-the-RAID-autostart-code-print-a-messa.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0033-fastboot-make-the-RAID-autostart-code-print-a-messa.patch
new file mode 100644
index 0000000000..55c6c1adae
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0033-fastboot-make-the-RAID-autostart-code-print-a-messa.patch
@@ -0,0 +1,32 @@
1From 799d0da9e645258b9d1ae11d4aac73c9474906e3 Mon Sep 17 00:00:00 2001
2From: Arjan van de Ven <arjan@linux.intel.com>
3Date: Sun, 20 Jul 2008 16:30:29 -0700
4Subject: [PATCH] fastboot: make the RAID autostart code print a message just before waiting
5
6As requested/suggested by Neil Brown: make the raid code print that it's
7about to wait for probing to be done as well as give a suggestion on how
8to disable the probing if the user doesn't use raid.
9
10Signed-off-by: Arjan van de Ven <arjan@linux.intel.com
11---
12 init/do_mounts_md.c | 4 +++-
13 1 files changed, 3 insertions(+), 1 deletions(-)
14
15diff --git a/init/do_mounts_md.c b/init/do_mounts_md.c
16index c0412a9..1ec5c41 100644
17--- a/init/do_mounts_md.c
18+++ b/init/do_mounts_md.c
19@@ -275,7 +275,9 @@ void __init md_run_setup(void)
20 * Since we don't want to detect and use half a raid array, we need to
21 * wait for the known devices to complete their probing
22 */
23- while (driver_probe_done() != 0)
24+ printk(KERN_INFO "md: Waiting for all devices to be available before autodetect\n");
25+ printk(KERN_INFO "md: If you don't use raid, use raid=noautodetect\n");
26+ while (driver_probe_done() < 0)
27 msleep(100);
28 int fd = sys_open("/dev/md0", 0, 0);
29 if (fd >= 0) {
30--
311.5.4.3
32
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0034-fastboot-fix-typo-in-init-Kconfig-text.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0034-fastboot-fix-typo-in-init-Kconfig-text.patch
new file mode 100644
index 0000000000..7426293549
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0034-fastboot-fix-typo-in-init-Kconfig-text.patch
@@ -0,0 +1,29 @@
1From 1a23ed42e1baf0481cc70c2f71d97b0bf0f1be70 Mon Sep 17 00:00:00 2001
2From: Ingo Molnar <mingo@elte.hu>
3Date: Thu, 31 Jul 2008 12:52:29 +0200
4Subject: [PATCH] fastboot: fix typo in init/Kconfig text
5
6noticed by Randy Dunlap.
7
8Reported-by: Randy Dunlap <randy.dunlap@oracle.com>
9Signed-off-by: Ingo Molnar <mingo@elte.hu>
10---
11 init/Kconfig | 2 +-
12 1 files changed, 1 insertions(+), 1 deletions(-)
13
14diff --git a/init/Kconfig b/init/Kconfig
15index 4f73780..6b4de4d 100644
16--- a/init/Kconfig
17+++ b/init/Kconfig
18@@ -530,7 +530,7 @@ config FASTBOOT
19 The fastboot option will cause the kernel to try to optimize
20 for faster boot.
21
22- This includes doing some of the device initialization asynchronous
23+ This includes doing some of the device initialization asynchronously
24 as well as opportunistically trying to mount the root fs early.
25
26 If unsure, say N.
27--
281.5.4.3
29
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0035-fastboot-remove-duplicate-unpack_to_rootfs.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0035-fastboot-remove-duplicate-unpack_to_rootfs.patch
new file mode 100644
index 0000000000..b8af74eaf2
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0035-fastboot-remove-duplicate-unpack_to_rootfs.patch
@@ -0,0 +1,161 @@
1From 8929dda869d51b953c8f300864da62297db8a74e Mon Sep 17 00:00:00 2001
2From: Li, Shaohua <shaohua.li@intel.com>
3Date: Wed, 13 Aug 2008 17:26:01 +0800
4Subject: [PATCH] fastboot: remove duplicate unpack_to_rootfs()
5
6we check if initrd is initramfs first and then do real unpack. The
7check isn't required, we can directly do unpack. If initrd isn't
8initramfs, we can remove garbage. In my laptop, this saves 0.1s boot
9time. This penalizes non-initramfs case, but now initramfs is mostly
10widely used.
11
12Signed-off-by: Shaohua Li <shaohua.li@intel.com>
13Acked-by: Arjan van de Ven <arjan@infradead.org>
14Signed-off-by: Ingo Molnar <mingo@elte.hu>
15---
16 init/initramfs.c | 71 ++++++++++++++++++++++++++++++++++++++++++-----------
17 1 files changed, 56 insertions(+), 15 deletions(-)
18
19diff --git a/init/initramfs.c b/init/initramfs.c
20index 644fc01..da8d030 100644
21--- a/init/initramfs.c
22+++ b/init/initramfs.c
23@@ -5,6 +5,7 @@
24 #include <linux/fcntl.h>
25 #include <linux/delay.h>
26 #include <linux/string.h>
27+#include <linux/dirent.h>
28 #include <linux/syscalls.h>
29
30 static __initdata char *message;
31@@ -121,8 +122,6 @@ static __initdata char *victim;
32 static __initdata unsigned count;
33 static __initdata loff_t this_header, next_header;
34
35-static __initdata int dry_run;
36-
37 static inline void __init eat(unsigned n)
38 {
39 victim += n;
40@@ -183,10 +182,6 @@ static int __init do_header(void)
41 parse_header(collected);
42 next_header = this_header + N_ALIGN(name_len) + body_len;
43 next_header = (next_header + 3) & ~3;
44- if (dry_run) {
45- read_into(name_buf, N_ALIGN(name_len), GotName);
46- return 0;
47- }
48 state = SkipIt;
49 if (name_len <= 0 || name_len > PATH_MAX)
50 return 0;
51@@ -257,8 +252,6 @@ static int __init do_name(void)
52 free_hash();
53 return 0;
54 }
55- if (dry_run)
56- return 0;
57 clean_path(collected, mode);
58 if (S_ISREG(mode)) {
59 int ml = maybe_link();
60@@ -423,10 +416,9 @@ static void __init flush_window(void)
61 outcnt = 0;
62 }
63
64-static char * __init unpack_to_rootfs(char *buf, unsigned len, int check_only)
65+static char * __init unpack_to_rootfs(char *buf, unsigned len)
66 {
67 int written;
68- dry_run = check_only;
69 header_buf = kmalloc(110, GFP_KERNEL);
70 symlink_buf = kmalloc(PATH_MAX + N_ALIGN(PATH_MAX) + 1, GFP_KERNEL);
71 name_buf = kmalloc(N_ALIGN(PATH_MAX), GFP_KERNEL);
72@@ -520,10 +512,57 @@ skip:
73 initrd_end = 0;
74 }
75
76+#define BUF_SIZE 1024
77+static void __init clean_rootfs(void)
78+{
79+ int fd;
80+ void *buf;
81+ struct linux_dirent64 *dirp;
82+ int count;
83+
84+ fd = sys_open("/", O_RDONLY, 0);
85+ WARN_ON(fd < 0);
86+ if (fd < 0)
87+ return;
88+ buf = kzalloc(BUF_SIZE, GFP_KERNEL);
89+ WARN_ON(!buf);
90+ if (!buf) {
91+ sys_close(fd);
92+ return;
93+ }
94+
95+ dirp = buf;
96+ count = sys_getdents64(fd, dirp, BUF_SIZE);
97+ while (count > 0) {
98+ while (count > 0) {
99+ struct stat st;
100+ int ret;
101+
102+ ret = sys_newlstat(dirp->d_name, &st);
103+ WARN_ON_ONCE(ret);
104+ if (!ret) {
105+ if (S_ISDIR(st.st_mode))
106+ sys_rmdir(dirp->d_name);
107+ else
108+ sys_unlink(dirp->d_name);
109+ }
110+
111+ count -= dirp->d_reclen;
112+ dirp = (void *)dirp + dirp->d_reclen;
113+ }
114+ dirp = buf;
115+ memset(buf, 0, BUF_SIZE);
116+ count = sys_getdents64(fd, dirp, BUF_SIZE);
117+ }
118+
119+ sys_close(fd);
120+ kfree(buf);
121+}
122+
123 static int __init populate_rootfs(void)
124 {
125 char *err = unpack_to_rootfs(__initramfs_start,
126- __initramfs_end - __initramfs_start, 0);
127+ __initramfs_end - __initramfs_start);
128 if (err)
129 panic(err);
130 if (initrd_start) {
131@@ -531,13 +570,15 @@ static int __init populate_rootfs(void)
132 int fd;
133 printk(KERN_INFO "checking if image is initramfs...");
134 err = unpack_to_rootfs((char *)initrd_start,
135- initrd_end - initrd_start, 1);
136+ initrd_end - initrd_start);
137 if (!err) {
138 printk(" it is\n");
139- unpack_to_rootfs((char *)initrd_start,
140- initrd_end - initrd_start, 0);
141 free_initrd();
142 return 0;
143+ } else {
144+ clean_rootfs();
145+ unpack_to_rootfs(__initramfs_start,
146+ __initramfs_end - __initramfs_start);
147 }
148 printk("it isn't (%s); looks like an initrd\n", err);
149 fd = sys_open("/initrd.image", O_WRONLY|O_CREAT, 0700);
150@@ -550,7 +591,7 @@ static int __init populate_rootfs(void)
151 #else
152 printk(KERN_INFO "Unpacking initramfs...");
153 err = unpack_to_rootfs((char *)initrd_start,
154- initrd_end - initrd_start, 0);
155+ initrd_end - initrd_start);
156 if (err)
157 panic(err);
158 printk(" done\n");
159--
1601.5.4.3
161
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0036-warning-fix-init-do_mounts_md-c.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0036-warning-fix-init-do_mounts_md-c.patch
new file mode 100644
index 0000000000..9ba44a892d
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0036-warning-fix-init-do_mounts_md-c.patch
@@ -0,0 +1,82 @@
1From fa3038625d7df2a1244c5b753069e7fdf99af3b5 Mon Sep 17 00:00:00 2001
2From: Ingo Molnar <mingo@elte.hu>
3Date: Mon, 18 Aug 2008 12:54:00 +0200
4Subject: [PATCH] warning: fix init do_mounts_md c
5MIME-Version: 1.0
6Content-Type: text/plain; charset=utf-8
7Content-Transfer-Encoding: 8bit
8
9fix warning:
10
11 init/do_mounts_md.c: In function ‘md_run_setup’:
12 init/do_mounts_md.c:282: warning: ISO C90 forbids mixed declarations and code
13
14also, use the opportunity to put the RAID autodetection code
15into a separate function - this also solves a checkpatch style warning.
16
17No code changed:
18
19md5:
20 aa36a35faef371b05f1974ad583bdbbd do_mounts_md.o.before.asm
21 aa36a35faef371b05f1974ad583bdbbd do_mounts_md.o.after.asm
22
23Signed-off-by: Ingo Molnar <mingo@elte.hu>
24---
25 init/do_mounts_md.c | 36 +++++++++++++++++++++---------------
26 1 files changed, 21 insertions(+), 15 deletions(-)
27
28diff --git a/init/do_mounts_md.c b/init/do_mounts_md.c
29index 1ec5c41..c0dfd3c 100644
30--- a/init/do_mounts_md.c
31+++ b/init/do_mounts_md.c
32@@ -264,26 +264,32 @@ static int __init raid_setup(char *str)
33 __setup("raid=", raid_setup);
34 __setup("md=", md_setup);
35
36+static void autodetect_raid(void)
37+{
38+ int fd;
39+
40+ /*
41+ * Since we don't want to detect and use half a raid array, we need to
42+ * wait for the known devices to complete their probing
43+ */
44+ printk(KERN_INFO "md: Waiting for all devices to be available before autodetect\n");
45+ printk(KERN_INFO "md: If you don't use raid, use raid=noautodetect\n");
46+ while (driver_probe_done() < 0)
47+ msleep(100);
48+ fd = sys_open("/dev/md0", 0, 0);
49+ if (fd >= 0) {
50+ sys_ioctl(fd, RAID_AUTORUN, raid_autopart);
51+ sys_close(fd);
52+ }
53+}
54+
55 void __init md_run_setup(void)
56 {
57 create_dev("/dev/md0", MKDEV(MD_MAJOR, 0));
58
59 if (raid_noautodetect)
60 printk(KERN_INFO "md: Skipping autodetection of RAID arrays. (raid=noautodetect)\n");
61- else {
62- /*
63- * Since we don't want to detect and use half a raid array, we need to
64- * wait for the known devices to complete their probing
65- */
66- printk(KERN_INFO "md: Waiting for all devices to be available before autodetect\n");
67- printk(KERN_INFO "md: If you don't use raid, use raid=noautodetect\n");
68- while (driver_probe_done() < 0)
69- msleep(100);
70- int fd = sys_open("/dev/md0", 0, 0);
71- if (fd >= 0) {
72- sys_ioctl(fd, RAID_AUTORUN, raid_autopart);
73- sys_close(fd);
74- }
75- }
76+ else
77+ autodetect_raid();
78 md_setup_drive();
79 }
80--
811.5.4.3
82
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0037-init-initramfs.c-unused-function-when-compiling-wit.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0037-init-initramfs.c-unused-function-when-compiling-wit.patch
new file mode 100644
index 0000000000..159f988670
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0037-init-initramfs.c-unused-function-when-compiling-wit.patch
@@ -0,0 +1,37 @@
1From b4931e6c151acad06b4c12dc7cdb634366d7d27a Mon Sep 17 00:00:00 2001
2From: Steven Noonan <steven@uplinklabs.net>
3Date: Mon, 8 Sep 2008 16:19:10 -0700
4Subject: [PATCH] init/initramfs.c: unused function when compiling without CONFIG_BLK_DEV_RAM
5
6Fixing compiler warning when the kernel isn't compiled with support
7for RAM block devices enabled.
8
9Signed-off-by: Steven Noonan <steven@uplinklabs.net>
10Signed-off-by: Ingo Molnar <mingo@elte.hu>
11---
12 init/initramfs.c | 2 ++
13 1 files changed, 2 insertions(+), 0 deletions(-)
14
15diff --git a/init/initramfs.c b/init/initramfs.c
16index da8d030..2f056e2 100644
17--- a/init/initramfs.c
18+++ b/init/initramfs.c
19@@ -512,6 +512,7 @@ skip:
20 initrd_end = 0;
21 }
22
23+#ifdef CONFIG_BLK_DEV_RAM
24 #define BUF_SIZE 1024
25 static void __init clean_rootfs(void)
26 {
27@@ -558,6 +559,7 @@ static void __init clean_rootfs(void)
28 sys_close(fd);
29 kfree(buf);
30 }
31+#endif
32
33 static int __init populate_rootfs(void)
34 {
35--
361.5.4.3
37
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0038-fastboot-fix-blackfin-breakage-due-to-vmlinux.lds-c.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0038-fastboot-fix-blackfin-breakage-due-to-vmlinux.lds-c.patch
new file mode 100644
index 0000000000..8d1e3f22f1
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0038-fastboot-fix-blackfin-breakage-due-to-vmlinux.lds-c.patch
@@ -0,0 +1,38 @@
1From 5e4f25d1f43991324794657655bbbc43983522a2 Mon Sep 17 00:00:00 2001
2From: Arjan van de Ven <arjan@infradead.org>
3Date: Wed, 10 Sep 2008 08:25:34 -0700
4Subject: [PATCH] fastboot: fix blackfin breakage due to vmlinux.lds change
5
6As reported by Mike Frysinger, the vmlinux.lds changes should
7have used VMLINUX_SYMBOL()...
8
9Reported-by: Mike Frysinger <vapier.adi@gmail.com>
10Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
11Acked-by: Bryan Wu <cooloney@kernel.org>
12Signed-off-by: Ingo Molnar <mingo@elte.hu>
13---
14 include/asm-generic/vmlinux.lds.h | 6 +++---
15 1 files changed, 3 insertions(+), 3 deletions(-)
16
17diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
18index b9be858..ccabc4e 100644
19--- a/include/asm-generic/vmlinux.lds.h
20+++ b/include/asm-generic/vmlinux.lds.h
21@@ -377,11 +377,11 @@
22 *(.initcall5s.init) \
23 *(.initcallrootfs.init) \
24 *(.initcall6s.init) \
25- __async_initcall_start = .; \
26+ VMLINUX_SYMBOL(__async_initcall_start) = .; \
27 *(.initcall6a.init) \
28- __async_initcall_end = .; \
29+ VMLINUX_SYMBOL(__async_initcall_end) = .; \
30 *(.initcall6.init) \
31- __device_initcall_end = .; \
32+ VMLINUX_SYMBOL(__device_initcall_end) = .; \
33 *(.initcall7.init) \
34 *(.initcall7s.init)
35
36--
371.5.4.3
38
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0039-Add-a-script-to-visualize-the-kernel-boot-process.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0039-Add-a-script-to-visualize-the-kernel-boot-process.patch
new file mode 100644
index 0000000000..da72d3bb75
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0039-Add-a-script-to-visualize-the-kernel-boot-process.patch
@@ -0,0 +1,183 @@
1From 77e9695b9d5c9ce761dedc193045d9cb64b8e245 Mon Sep 17 00:00:00 2001
2From: Arjan van de Ven <arjan@linux.intel.com>
3Date: Sat, 13 Sep 2008 09:36:06 -0700
4Subject: [PATCH] Add a script to visualize the kernel boot process / time
5
6When optimizing the kernel boot time, it's very valuable to visualize
7what is going on at which time. In addition, with the fastboot asynchronous
8initcall level, it's very valuable to see which initcall gets run where
9and when.
10
11This patch adds a script to turn a dmesg into a SVG graph (that can be
12shown with tools such as InkScape, Gimp or Firefox) and a small change
13to the initcall code to print the PID of the thread calling the initcall
14(so that the script can work out the parallelism).
15
16Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
17---
18 init/main.c | 3 +-
19 scripts/bootgraph.pl | 138 ++++++++++++++++++++++++++++++++++++++++++++++++++
20 2 files changed, 140 insertions(+), 1 deletions(-)
21 create mode 100644 scripts/bootgraph.pl
22
23diff --git a/init/main.c b/init/main.c
24index a1b95f3..14f2609 100644
25--- a/init/main.c
26+++ b/init/main.c
27@@ -708,7 +708,8 @@ int do_one_initcall(initcall_t fn)
28 int result;
29
30 if (initcall_debug) {
31- print_fn_descriptor_symbol("calling %s\n", fn);
32+ print_fn_descriptor_symbol("calling %s", fn);
33+ printk(" @ %i\n", task_pid_nr(current));
34 t0 = ktime_get();
35 }
36
37diff --git a/scripts/bootgraph.pl b/scripts/bootgraph.pl
38new file mode 100644
39index 0000000..d459b8b
40--- /dev/null
41+++ b/scripts/bootgraph.pl
42@@ -0,0 +1,138 @@
43+#!/usr/bin/perl
44+
45+# Copyright 2008, Intel Corporation
46+#
47+# This file is part of the Linux kernel
48+#
49+# This program file is free software; you can redistribute it and/or modify it
50+# under the terms of the GNU General Public License as published by the
51+# Free Software Foundation; version 2 of the License.
52+#
53+# This program is distributed in the hope that it will be useful, but WITHOUT
54+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
55+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
56+# for more details.
57+#
58+# You should have received a copy of the GNU General Public License
59+# along with this program in a file named COPYING; if not, write to the
60+# Free Software Foundation, Inc.,
61+# 51 Franklin Street, Fifth Floor,
62+# Boston, MA 02110-1301 USA
63+#
64+# Authors:
65+# Arjan van de Ven <arjan@linux.intel.com>
66+
67+
68+#
69+# This script turns a dmesg output into a SVG graphic that shows which
70+# functions take how much time. You can view SVG graphics with various
71+# programs, including Inkscape, The Gimp and Firefox.
72+#
73+#
74+# For this script to work, the kernel needs to be compiled with the
75+# CONFIG_PRINTK_TIME configuration option enabled, and with
76+# "initcall_debug" passed on the kernel command line.
77+#
78+# usage:
79+# dmesg | perl scripts/bootgraph.pl > output.svg
80+#
81+
82+my @rows;
83+my %start, %end, %row;
84+my $done = 0;
85+my $rowcount = 0;
86+my $maxtime = 0;
87+my $count = 0;
88+while (<>) {
89+ my $line = $_;
90+ if ($line =~ /([0-9\.]+)\] calling ([a-zA-Z\_]+)\+/) {
91+ my $func = $2;
92+ if ($done == 0) {
93+ $start{$func} = $1;
94+ }
95+ $row{$func} = 1;
96+ if ($line =~ /\@ ([0-9]+)/) {
97+ my $pid = $1;
98+ if (!defined($rows[$pid])) {
99+ $rowcount = $rowcount + 1;
100+ $rows[$pid] = $rowcount;
101+ }
102+ $row{$func} = $rows[$pid];
103+ }
104+ $count = $count + 1;
105+ }
106+
107+ if ($line =~ /([0-9\.]+)\] initcall ([a-zA-Z\_]+)\+.*returned/) {
108+ if ($done == 0) {
109+ $end{$2} = $1;
110+ $maxtime = $1;
111+ }
112+ }
113+ if ($line =~ /Write protecting the/) {
114+ $done = 1;
115+ }
116+}
117+
118+if ($count == 0) {
119+ print "No data found in the dmesg. Make sure CONFIG_PRINTK_TIME is enabled and\n";
120+ print "that initcall_debug is passed on the kernel command line.\n\n";
121+ print "Usage: \n";
122+ print " dmesg | perl scripts/bootgraph.pl > output.svg\n\n";
123+ exit;
124+}
125+
126+print "<?xml version=\"1.0\" standalone=\"no\"?> \n";
127+print "<svg width=\"1000\" height=\"100%\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\">\n";
128+
129+my @styles;
130+
131+$styles[0] = "fill:rgb(0,0,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
132+$styles[1] = "fill:rgb(0,255,0);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
133+$styles[2] = "fill:rgb(255,0,20);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
134+$styles[3] = "fill:rgb(255,255,20);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
135+$styles[4] = "fill:rgb(255,0,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
136+$styles[5] = "fill:rgb(0,255,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
137+$styles[6] = "fill:rgb(0,128,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
138+$styles[7] = "fill:rgb(0,255,128);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
139+$styles[8] = "fill:rgb(255,0,128);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
140+$styles[9] = "fill:rgb(255,255,128);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
141+$styles[10] = "fill:rgb(255,128,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
142+$styles[11] = "fill:rgb(128,255,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
143+
144+my $mult = 950.0 / $maxtime;
145+my $threshold = 0.0500 / $maxtime;
146+my $stylecounter = 0;
147+while (($key,$value) = each %start) {
148+ my $duration = $end{$key} - $start{$key};
149+
150+ if ($duration >= $threshold) {
151+ my $s, $s2, $e, $y;
152+ $s = $value * $mult;
153+ $s2 = $s + 6;
154+ $e = $end{$key} * $mult;
155+ $w = $e - $s;
156+
157+ $y = $row{$key} * 150;
158+ $y2 = $y + 4;
159+
160+ $style = $styles[$stylecounter];
161+ $stylecounter = $stylecounter + 1;
162+ if ($stylecounter > 11) {
163+ $stylecounter = 0;
164+ };
165+
166+ print "<rect x=\"$s\" width=\"$w\" y=\"$y\" height=\"145\" style=\"$style\"/>\n";
167+ print "<text transform=\"translate($s2,$y2) rotate(90)\">$key</text>\n";
168+ }
169+}
170+
171+
172+# print the time line on top
173+my $time = 0.0;
174+while ($time < $maxtime) {
175+ my $s2 = $time * $mult;
176+ print "<text transform=\"translate($s2,89) rotate(90)\">$time</text>\n";
177+ $time = $time + 0.1;
178+}
179+
180+print "</svg>\n";
181--
1821.5.4.3
183
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0040-fastboot-fix-issues-and-improve-output-of-bootgraph.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0040-fastboot-fix-issues-and-improve-output-of-bootgraph.patch
new file mode 100644
index 0000000000..0daba9d2cf
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0040-fastboot-fix-issues-and-improve-output-of-bootgraph.patch
@@ -0,0 +1,91 @@
1From 5470e09b98074974316bbf98c8b8da01d670c2a4 Mon Sep 17 00:00:00 2001
2From: Arjan van de Ven <arjan@linux.intel.com>
3Date: Sun, 14 Sep 2008 15:30:52 -0700
4Subject: [PATCH] fastboot: fix issues and improve output of bootgraph.pl
5
6David Sanders reported some issues with bootgraph.pl's display
7of his sytems bootup; this commit fixes these by scaling the graph
8not from 0 - end time but from the first initcall to the end time;
9the minimum display size etc also now need to scale with this, as does
10the axis display.
11
12Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
13---
14 scripts/bootgraph.pl | 25 +++++++++++++++++--------
15 1 files changed, 17 insertions(+), 8 deletions(-)
16
17diff --git a/scripts/bootgraph.pl b/scripts/bootgraph.pl
18index d459b8b..4e5f4ab 100644
19--- a/scripts/bootgraph.pl
20+++ b/scripts/bootgraph.pl
21@@ -42,6 +42,7 @@ my %start, %end, %row;
22 my $done = 0;
23 my $rowcount = 0;
24 my $maxtime = 0;
25+my $firsttime = 100;
26 my $count = 0;
27 while (<>) {
28 my $line = $_;
29@@ -49,6 +50,9 @@ while (<>) {
30 my $func = $2;
31 if ($done == 0) {
32 $start{$func} = $1;
33+ if ($1 < $firsttime) {
34+ $firsttime = $1;
35+ }
36 }
37 $row{$func} = 1;
38 if ($line =~ /\@ ([0-9]+)/) {
39@@ -71,6 +75,9 @@ while (<>) {
40 if ($line =~ /Write protecting the/) {
41 $done = 1;
42 }
43+ if ($line =~ /Freeing unused kernel memory/) {
44+ $done = 1;
45+ }
46 }
47
48 if ($count == 0) {
49@@ -99,17 +106,17 @@ $styles[9] = "fill:rgb(255,255,128);fill-opacity:0.5;stroke-width:1;stroke:rgb(0
50 $styles[10] = "fill:rgb(255,128,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
51 $styles[11] = "fill:rgb(128,255,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
52
53-my $mult = 950.0 / $maxtime;
54-my $threshold = 0.0500 / $maxtime;
55+my $mult = 950.0 / ($maxtime - $firsttime);
56+my $threshold = ($maxtime - $firsttime) / 60.0;
57 my $stylecounter = 0;
58 while (($key,$value) = each %start) {
59 my $duration = $end{$key} - $start{$key};
60
61 if ($duration >= $threshold) {
62 my $s, $s2, $e, $y;
63- $s = $value * $mult;
64+ $s = ($value - $firsttime) * $mult;
65 $s2 = $s + 6;
66- $e = $end{$key} * $mult;
67+ $e = ($end{$key} - $firsttime) * $mult;
68 $w = $e - $s;
69
70 $y = $row{$key} * 150;
71@@ -128,11 +135,13 @@ while (($key,$value) = each %start) {
72
73
74 # print the time line on top
75-my $time = 0.0;
76+my $time = $firsttime;
77+my $step = ($maxtime - $firsttime) / 15;
78 while ($time < $maxtime) {
79- my $s2 = $time * $mult;
80- print "<text transform=\"translate($s2,89) rotate(90)\">$time</text>\n";
81- $time = $time + 0.1;
82+ my $s2 = ($time - $firsttime) * $mult;
83+ my $tm = int($time * 100) / 100.0;
84+ print "<text transform=\"translate($s2,89) rotate(90)\">$tm</text>\n";
85+ $time = $time + $step;
86 }
87
88 print "</svg>\n";
89--
901.5.4.3
91
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0041-r8169-8101e.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0041-r8169-8101e.patch
new file mode 100644
index 0000000000..781c9a127e
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0041-r8169-8101e.patch
@@ -0,0 +1,940 @@
1From 771c0d99c0ab3ca7f1a9bc400e8259171b518d5f Mon Sep 17 00:00:00 2001
2From: Francois Romieu <romieu@fr.zoreil.com>
3Date: Thu, 21 Aug 2008 23:20:40 +0200
4Subject: [PATCH] r8169: fix RxMissed register access
5
6- the register location is defined for the 8169 chipset only and
7 there is no 8169 beyond RTL_GIGA_MAC_VER_06
8- only the lower 3 bytes of the register are valid
9
10Fixes:
111. http://bugzilla.kernel.org/show_bug.cgi?id=10180
122. http://bugzilla.kernel.org/show_bug.cgi?id=11062 (bits of)
13
14Tested by Hermann Gausterer and Adam Huffman.
15
16Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
17Cc: Edward Hsu <edward_hsu@realtek.com.tw>
18---
19 drivers/net/r8169.c | 25 ++++++++++++++-----------
20 1 files changed, 14 insertions(+), 11 deletions(-)
21
22diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
23index 0f6f974..4190ee7 100644
24--- a/drivers/net/r8169.c
25+++ b/drivers/net/r8169.c
26@@ -2099,8 +2099,6 @@ static void rtl_hw_start_8168(struct net_device *dev)
27
28 RTL_R8(IntrMask);
29
30- RTL_W32(RxMissed, 0);
31-
32 rtl_set_rx_mode(dev);
33
34 RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
35@@ -2143,8 +2141,6 @@ static void rtl_hw_start_8101(struct net_device *dev)
36
37 RTL_R8(IntrMask);
38
39- RTL_W32(RxMissed, 0);
40-
41 rtl_set_rx_mode(dev);
42
43 RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
44@@ -2922,6 +2918,17 @@ static int rtl8169_poll(struct napi_struct *napi, int budget)
45 return work_done;
46 }
47
48+static void rtl8169_rx_missed(struct net_device *dev, void __iomem *ioaddr)
49+{
50+ struct rtl8169_private *tp = netdev_priv(dev);
51+
52+ if (tp->mac_version > RTL_GIGA_MAC_VER_06)
53+ return;
54+
55+ dev->stats.rx_missed_errors += (RTL_R32(RxMissed) & 0xffffff);
56+ RTL_W32(RxMissed, 0);
57+}
58+
59 static void rtl8169_down(struct net_device *dev)
60 {
61 struct rtl8169_private *tp = netdev_priv(dev);
62@@ -2939,9 +2946,7 @@ core_down:
63
64 rtl8169_asic_down(ioaddr);
65
66- /* Update the error counts. */
67- dev->stats.rx_missed_errors += RTL_R32(RxMissed);
68- RTL_W32(RxMissed, 0);
69+ rtl8169_rx_missed(dev, ioaddr);
70
71 spin_unlock_irq(&tp->lock);
72
73@@ -3063,8 +3068,7 @@ static struct net_device_stats *rtl8169_get_stats(struct net_device *dev)
74
75 if (netif_running(dev)) {
76 spin_lock_irqsave(&tp->lock, flags);
77- dev->stats.rx_missed_errors += RTL_R32(RxMissed);
78- RTL_W32(RxMissed, 0);
79+ rtl8169_rx_missed(dev, ioaddr);
80 spin_unlock_irqrestore(&tp->lock, flags);
81 }
82
83@@ -3089,8 +3093,7 @@ static int rtl8169_suspend(struct pci_dev *pdev, pm_message_t state)
84
85 rtl8169_asic_down(ioaddr);
86
87- dev->stats.rx_missed_errors += RTL_R32(RxMissed);
88- RTL_W32(RxMissed, 0);
89+ rtl8169_rx_missed(dev, ioaddr);
90
91 spin_unlock_irq(&tp->lock);
92
93--
941.5.3.3
95
96From 6ee4bc96d446a9c466a18b715c7ab2d662c03ebd Mon Sep 17 00:00:00 2001
97From: Francois Romieu <romieu@fr.zoreil.com>
98Date: Sat, 26 Jul 2008 14:26:06 +0200
99Subject: [PATCH] r8169: get ethtool settings through the generic mii helper
100
101It avoids to report unsupported link capabilities with
102the fast-ethernet only 8101/8102.
103
104Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
105Tested-by: Martin Capitanio <martin@capitanio.org>
106Fixed-by: Ivan Vecera <ivecera@redhat.com>
107Cc: Edward Hsu <edward_hsu@realtek.com.tw>
108---
109 drivers/net/r8169.c | 99 +++++++++++++++++++++++---------------------------
110 1 files changed, 46 insertions(+), 53 deletions(-)
111
112diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
113index 4190ee7..7e026a6 100644
114--- a/drivers/net/r8169.c
115+++ b/drivers/net/r8169.c
116@@ -370,8 +370,9 @@ struct ring_info {
117 };
118
119 enum features {
120- RTL_FEATURE_WOL = (1 << 0),
121- RTL_FEATURE_MSI = (1 << 1),
122+ RTL_FEATURE_WOL = (1 << 0),
123+ RTL_FEATURE_MSI = (1 << 1),
124+ RTL_FEATURE_GMII = (1 << 2),
125 };
126
127 struct rtl8169_private {
128@@ -406,13 +407,15 @@ struct rtl8169_private {
129 struct vlan_group *vlgrp;
130 #endif
131 int (*set_speed)(struct net_device *, u8 autoneg, u16 speed, u8 duplex);
132- void (*get_settings)(struct net_device *, struct ethtool_cmd *);
133+ int (*get_settings)(struct net_device *, struct ethtool_cmd *);
134 void (*phy_reset_enable)(void __iomem *);
135 void (*hw_start)(struct net_device *);
136 unsigned int (*phy_reset_pending)(void __iomem *);
137 unsigned int (*link_ok)(void __iomem *);
138 struct delayed_work task;
139 unsigned features;
140+
141+ struct mii_if_info mii;
142 };
143
144 MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>");
145@@ -482,6 +485,23 @@ static int mdio_read(void __iomem *ioaddr, int reg_addr)
146 return value;
147 }
148
149+static void rtl_mdio_write(struct net_device *dev, int phy_id, int location,
150+ int val)
151+{
152+ struct rtl8169_private *tp = netdev_priv(dev);
153+ void __iomem *ioaddr = tp->mmio_addr;
154+
155+ mdio_write(ioaddr, location, val);
156+}
157+
158+static int rtl_mdio_read(struct net_device *dev, int phy_id, int location)
159+{
160+ struct rtl8169_private *tp = netdev_priv(dev);
161+ void __iomem *ioaddr = tp->mmio_addr;
162+
163+ return mdio_read(ioaddr, location);
164+}
165+
166 static void rtl8169_irq_mask_and_ack(void __iomem *ioaddr)
167 {
168 RTL_W16(IntrMask, 0x0000);
169@@ -850,7 +870,7 @@ static int rtl8169_rx_vlan_skb(struct rtl8169_private *tp, struct RxDesc *desc,
170
171 #endif
172
173-static void rtl8169_gset_tbi(struct net_device *dev, struct ethtool_cmd *cmd)
174+static int rtl8169_gset_tbi(struct net_device *dev, struct ethtool_cmd *cmd)
175 {
176 struct rtl8169_private *tp = netdev_priv(dev);
177 void __iomem *ioaddr = tp->mmio_addr;
178@@ -867,65 +887,29 @@ static void rtl8169_gset_tbi(struct net_device *dev, struct ethtool_cmd *cmd)
179
180 cmd->speed = SPEED_1000;
181 cmd->duplex = DUPLEX_FULL; /* Always set */
182+
183+ return 0;
184 }
185
186-static void rtl8169_gset_xmii(struct net_device *dev, struct ethtool_cmd *cmd)
187+static int rtl8169_gset_xmii(struct net_device *dev, struct ethtool_cmd *cmd)
188 {
189 struct rtl8169_private *tp = netdev_priv(dev);
190- void __iomem *ioaddr = tp->mmio_addr;
191- u8 status;
192-
193- cmd->supported = SUPPORTED_10baseT_Half |
194- SUPPORTED_10baseT_Full |
195- SUPPORTED_100baseT_Half |
196- SUPPORTED_100baseT_Full |
197- SUPPORTED_1000baseT_Full |
198- SUPPORTED_Autoneg |
199- SUPPORTED_TP;
200-
201- cmd->autoneg = 1;
202- cmd->advertising = ADVERTISED_TP | ADVERTISED_Autoneg;
203-
204- if (tp->phy_auto_nego_reg & ADVERTISE_10HALF)
205- cmd->advertising |= ADVERTISED_10baseT_Half;
206- if (tp->phy_auto_nego_reg & ADVERTISE_10FULL)
207- cmd->advertising |= ADVERTISED_10baseT_Full;
208- if (tp->phy_auto_nego_reg & ADVERTISE_100HALF)
209- cmd->advertising |= ADVERTISED_100baseT_Half;
210- if (tp->phy_auto_nego_reg & ADVERTISE_100FULL)
211- cmd->advertising |= ADVERTISED_100baseT_Full;
212- if (tp->phy_1000_ctrl_reg & ADVERTISE_1000FULL)
213- cmd->advertising |= ADVERTISED_1000baseT_Full;
214-
215- status = RTL_R8(PHYstatus);
216-
217- if (status & _1000bpsF)
218- cmd->speed = SPEED_1000;
219- else if (status & _100bps)
220- cmd->speed = SPEED_100;
221- else if (status & _10bps)
222- cmd->speed = SPEED_10;
223-
224- if (status & TxFlowCtrl)
225- cmd->advertising |= ADVERTISED_Asym_Pause;
226- if (status & RxFlowCtrl)
227- cmd->advertising |= ADVERTISED_Pause;
228-
229- cmd->duplex = ((status & _1000bpsF) || (status & FullDup)) ?
230- DUPLEX_FULL : DUPLEX_HALF;
231+
232+ return mii_ethtool_gset(&tp->mii, cmd);
233 }
234
235 static int rtl8169_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
236 {
237 struct rtl8169_private *tp = netdev_priv(dev);
238 unsigned long flags;
239+ int rc;
240
241 spin_lock_irqsave(&tp->lock, flags);
242
243- tp->get_settings(dev, cmd);
244+ rc = tp->get_settings(dev, cmd);
245
246 spin_unlock_irqrestore(&tp->lock, flags);
247- return 0;
248+ return rc;
249 }
250
251 static void rtl8169_get_regs(struct net_device *dev, struct ethtool_regs *regs,
252@@ -1513,7 +1497,7 @@ static const struct rtl_cfg_info {
253 unsigned int align;
254 u16 intr_event;
255 u16 napi_event;
256- unsigned msi;
257+ unsigned features;
258 } rtl_cfg_infos [] = {
259 [RTL_CFG_0] = {
260 .hw_start = rtl_hw_start_8169,
261@@ -1522,7 +1506,7 @@ static const struct rtl_cfg_info {
262 .intr_event = SYSErr | LinkChg | RxOverflow |
263 RxFIFOOver | TxErr | TxOK | RxOK | RxErr,
264 .napi_event = RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow,
265- .msi = 0
266+ .features = RTL_FEATURE_GMII
267 },
268 [RTL_CFG_1] = {
269 .hw_start = rtl_hw_start_8168,
270@@ -1531,7 +1515,7 @@ static const struct rtl_cfg_info {
271 .intr_event = SYSErr | LinkChg | RxOverflow |
272 TxErr | TxOK | RxOK | RxErr,
273 .napi_event = TxErr | TxOK | RxOK | RxOverflow,
274- .msi = RTL_FEATURE_MSI
275+ .features = RTL_FEATURE_GMII | RTL_FEATURE_MSI
276 },
277 [RTL_CFG_2] = {
278 .hw_start = rtl_hw_start_8101,
279@@ -1540,7 +1524,7 @@ static const struct rtl_cfg_info {
280 .intr_event = SYSErr | LinkChg | RxOverflow | PCSTimeout |
281 RxFIFOOver | TxErr | TxOK | RxOK | RxErr,
282 .napi_event = RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow,
283- .msi = RTL_FEATURE_MSI
284+ .features = RTL_FEATURE_MSI
285 }
286 };
287
288@@ -1552,7 +1536,7 @@ static unsigned rtl_try_msi(struct pci_dev *pdev, void __iomem *ioaddr,
289 u8 cfg2;
290
291 cfg2 = RTL_R8(Config2) & ~MSIEnable;
292- if (cfg->msi) {
293+ if (cfg->features & RTL_FEATURE_MSI) {
294 if (pci_enable_msi(pdev)) {
295 dev_info(&pdev->dev, "no MSI. Back to INTx.\n");
296 } else {
297@@ -1578,6 +1562,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
298 const struct rtl_cfg_info *cfg = rtl_cfg_infos + ent->driver_data;
299 const unsigned int region = cfg->region;
300 struct rtl8169_private *tp;
301+ struct mii_if_info *mii;
302 struct net_device *dev;
303 void __iomem *ioaddr;
304 unsigned int i;
305@@ -1602,6 +1587,14 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
306 tp->pci_dev = pdev;
307 tp->msg_enable = netif_msg_init(debug.msg_enable, R8169_MSG_DEFAULT);
308
309+ mii = &tp->mii;
310+ mii->dev = dev;
311+ mii->mdio_read = rtl_mdio_read;
312+ mii->mdio_write = rtl_mdio_write;
313+ mii->phy_id_mask = 0x1f;
314+ mii->reg_num_mask = 0x1f;
315+ mii->supports_gmii = !!(cfg->features & RTL_FEATURE_GMII);
316+
317 /* enable device (incl. PCI PM wakeup and hotplug setup) */
318 rc = pci_enable_device(pdev);
319 if (rc < 0) {
320--
3211.5.3.3
322
323From ef60b2a38e223a331e13ef503aee7cd5d4d5c12c Mon Sep 17 00:00:00 2001
324From: Hugh Dickins <hugh@veritas.com>
325Date: Mon, 8 Sep 2008 21:49:01 +0100
326Subject: [PATCH] r8169: select MII in Kconfig
327
328drivers/built-in.o: In function `rtl8169_gset_xmii':
329r8169.c:(.text+0x82259): undefined reference to `mii_ethtool_gset'
330suggests that the r8169 driver now needs to select MII.
331
332Signed-off-by: Hugh Dickins <hugh@veritas.com>
333Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
334Cc: Edward Hsu <edward_hsu@realtek.com.tw>
335---
336 drivers/net/Kconfig | 1 +
337 1 files changed, 1 insertions(+), 0 deletions(-)
338
339diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
340index 4a11296..60a0453 100644
341--- a/drivers/net/Kconfig
342+++ b/drivers/net/Kconfig
343@@ -2046,6 +2046,7 @@ config R8169
344 tristate "Realtek 8169 gigabit ethernet support"
345 depends on PCI
346 select CRC32
347+ select MII
348 ---help---
349 Say Y here if you have a Realtek 8169 PCI Gigabit Ethernet adapter.
350
351--
3521.5.3.3
353
354From bca31864fca6004c4a4a9bd549e95c93b3c3bb10 Mon Sep 17 00:00:00 2001
355From: Francois Romieu <romieu@fr.zoreil.com>
356Date: Sat, 2 Aug 2008 15:50:02 +0200
357Subject: [PATCH] r8169: Tx performance tweak helper
358
359Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
360Cc: Edward Hsu <edward_hsu@realtek.com.tw>
361---
362 drivers/net/r8169.c | 15 ++++++++++-----
363 1 files changed, 10 insertions(+), 5 deletions(-)
364
365diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
366index 7e026a6..eea96fb 100644
367--- a/drivers/net/r8169.c
368+++ b/drivers/net/r8169.c
369@@ -2054,12 +2054,20 @@ static void rtl_hw_start_8169(struct net_device *dev)
370 RTL_W16(IntrMask, tp->intr_event);
371 }
372
373+static void rtl_tx_performance_tweak(struct pci_dev *pdev, u8 force)
374+{
375+ u8 ctl;
376+
377+ pci_read_config_byte(pdev, 0x69, &ctl);
378+ ctl = (ctl & ~0x70) | force;
379+ pci_write_config_byte(pdev, 0x69, ctl);
380+}
381+
382 static void rtl_hw_start_8168(struct net_device *dev)
383 {
384 struct rtl8169_private *tp = netdev_priv(dev);
385 void __iomem *ioaddr = tp->mmio_addr;
386 struct pci_dev *pdev = tp->pci_dev;
387- u8 ctl;
388
389 RTL_W8(Cfg9346, Cfg9346_Unlock);
390
391@@ -2073,10 +2081,7 @@ static void rtl_hw_start_8168(struct net_device *dev)
392
393 RTL_W16(CPlusCmd, tp->cp_cmd);
394
395- /* Tx performance tweak. */
396- pci_read_config_byte(pdev, 0x69, &ctl);
397- ctl = (ctl & ~0x70) | 0x50;
398- pci_write_config_byte(pdev, 0x69, ctl);
399+ rtl_tx_performance_tweak(pdev, 0x50);
400
401 RTL_W16(IntrMitigate, 0x5151);
402
403--
4041.5.3.3
405
406From 7a929ae7d5a3618f56bf1ccaf8c62df628e820aa Mon Sep 17 00:00:00 2001
407From: Francois Romieu <romieu@fr.zoreil.com>
408Date: Sat, 5 Jul 2008 00:21:15 +0200
409Subject: [PATCH] r8169: use pci_find_capability for the PCI-E features
410
411Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
412Cc: Edward Hsu <edward_hsu@realtek.com.tw>
413---
414 drivers/net/r8169.c | 32 ++++++++++++++++++++++++--------
415 1 files changed, 24 insertions(+), 8 deletions(-)
416
417diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
418index eea96fb..5c00522 100644
419--- a/drivers/net/r8169.c
420+++ b/drivers/net/r8169.c
421@@ -61,6 +61,7 @@ static const int multicast_filter_limit = 32;
422 /* MAC address length */
423 #define MAC_ADDR_LEN 6
424
425+#define MAX_READ_REQUEST_SHIFT 12
426 #define RX_FIFO_THRESH 7 /* 7 means NO threshold, Rx buffer level before first PCI xfer. */
427 #define RX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */
428 #define TX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */
429@@ -412,6 +413,7 @@ struct rtl8169_private {
430 void (*hw_start)(struct net_device *);
431 unsigned int (*phy_reset_pending)(void __iomem *);
432 unsigned int (*link_ok)(void __iomem *);
433+ int pcie_cap;
434 struct delayed_work task;
435 unsigned features;
436
437@@ -1663,6 +1665,10 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
438 goto err_out_free_res_4;
439 }
440
441+ tp->pcie_cap = pci_find_capability(pdev, PCI_CAP_ID_EXP);
442+ if (!tp->pcie_cap && netif_msg_probe(tp))
443+ dev_info(&pdev->dev, "no PCI Express capability\n");
444+
445 /* Unneeded ? Don't mess with Mrs. Murphy. */
446 rtl8169_irq_mask_and_ack(ioaddr);
447
448@@ -2054,13 +2060,19 @@ static void rtl_hw_start_8169(struct net_device *dev)
449 RTL_W16(IntrMask, tp->intr_event);
450 }
451
452-static void rtl_tx_performance_tweak(struct pci_dev *pdev, u8 force)
453+static void rtl_tx_performance_tweak(struct pci_dev *pdev, u16 force)
454 {
455- u8 ctl;
456+ struct net_device *dev = pci_get_drvdata(pdev);
457+ struct rtl8169_private *tp = netdev_priv(dev);
458+ int cap = tp->pcie_cap;
459+
460+ if (cap) {
461+ u16 ctl;
462
463- pci_read_config_byte(pdev, 0x69, &ctl);
464- ctl = (ctl & ~0x70) | force;
465- pci_write_config_byte(pdev, 0x69, ctl);
466+ pci_read_config_word(pdev, cap + PCI_EXP_DEVCTL, &ctl);
467+ ctl = (ctl & ~PCI_EXP_DEVCTL_READRQ) | force;
468+ pci_write_config_word(pdev, cap + PCI_EXP_DEVCTL, ctl);
469+ }
470 }
471
472 static void rtl_hw_start_8168(struct net_device *dev)
473@@ -2081,7 +2093,7 @@ static void rtl_hw_start_8168(struct net_device *dev)
474
475 RTL_W16(CPlusCmd, tp->cp_cmd);
476
477- rtl_tx_performance_tweak(pdev, 0x50);
478+ rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
479
480 RTL_W16(IntrMitigate, 0x5151);
481
482@@ -2114,8 +2126,12 @@ static void rtl_hw_start_8101(struct net_device *dev)
483
484 if ((tp->mac_version == RTL_GIGA_MAC_VER_13) ||
485 (tp->mac_version == RTL_GIGA_MAC_VER_16)) {
486- pci_write_config_word(pdev, 0x68, 0x00);
487- pci_write_config_word(pdev, 0x69, 0x08);
488+ int cap = tp->pcie_cap;
489+
490+ if (cap) {
491+ pci_write_config_word(pdev, cap + PCI_EXP_DEVCTL,
492+ PCI_EXP_DEVCTL_NOSNOOP_EN);
493+ }
494 }
495
496 RTL_W8(Cfg9346, Cfg9346_Unlock);
497--
4981.5.3.3
499
500From ba648bdcbca93084360d348eb43dde4b19b2489e Mon Sep 17 00:00:00 2001
501From: Francois Romieu <romieu@fr.zoreil.com>
502Date: Sun, 1 Jun 2008 22:37:49 +0200
503Subject: [PATCH] r8169: add 8168/8101 registers description
504
505Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
506Cc: Edward Hsu <edward_hsu@realtek.com.tw>
507---
508 drivers/net/r8169.c | 47 +++++++++++++++++++++++++++++++++++++++++++----
509 1 files changed, 43 insertions(+), 4 deletions(-)
510
511diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
512index 5c00522..0b8db03 100644
513--- a/drivers/net/r8169.c
514+++ b/drivers/net/r8169.c
515@@ -197,9 +197,6 @@ enum rtl_registers {
516 Config5 = 0x56,
517 MultiIntr = 0x5c,
518 PHYAR = 0x60,
519- TBICSR = 0x64,
520- TBI_ANAR = 0x68,
521- TBI_LPAR = 0x6a,
522 PHYstatus = 0x6c,
523 RxMaxSize = 0xda,
524 CPlusCmd = 0xe0,
525@@ -213,6 +210,32 @@ enum rtl_registers {
526 FuncForceEvent = 0xfc,
527 };
528
529+enum rtl8110_registers {
530+ TBICSR = 0x64,
531+ TBI_ANAR = 0x68,
532+ TBI_LPAR = 0x6a,
533+};
534+
535+enum rtl8168_8101_registers {
536+ CSIDR = 0x64,
537+ CSIAR = 0x68,
538+#define CSIAR_FLAG 0x80000000
539+#define CSIAR_WRITE_CMD 0x80000000
540+#define CSIAR_BYTE_ENABLE 0x0f
541+#define CSIAR_BYTE_ENABLE_SHIFT 12
542+#define CSIAR_ADDR_MASK 0x0fff
543+
544+ EPHYAR = 0x80,
545+#define EPHYAR_FLAG 0x80000000
546+#define EPHYAR_WRITE_CMD 0x80000000
547+#define EPHYAR_REG_MASK 0x1f
548+#define EPHYAR_REG_SHIFT 16
549+#define EPHYAR_DATA_MASK 0xffff
550+ DBG_REG = 0xd1,
551+#define FIX_NAK_1 (1 << 4)
552+#define FIX_NAK_2 (1 << 3)
553+};
554+
555 enum rtl_register_content {
556 /* InterruptStatusBits */
557 SYSErr = 0x8000,
558@@ -266,7 +289,13 @@ enum rtl_register_content {
559 TxDMAShift = 8, /* DMA burst value (0-7) is shift this many bits */
560
561 /* Config1 register p.24 */
562+ LEDS1 = (1 << 7),
563+ LEDS0 = (1 << 6),
564 MSIEnable = (1 << 5), /* Enable Message Signaled Interrupt */
565+ Speed_down = (1 << 4),
566+ MEMMAP = (1 << 3),
567+ IOMAP = (1 << 2),
568+ VPD = (1 << 1),
569 PMEnable = (1 << 0), /* Power Management Enable */
570
571 /* Config2 register p. 25 */
572@@ -276,6 +305,7 @@ enum rtl_register_content {
573 /* Config3 register p.25 */
574 MagicPacket = (1 << 5), /* Wake up when receives a Magic Packet */
575 LinkUp = (1 << 4), /* Wake up when the cable connection is re-established */
576+ Beacon_en = (1 << 0), /* 8168 only. Reserved in the 8168b */
577
578 /* Config5 register p.27 */
579 BWF = (1 << 6), /* Accept Broadcast wakeup frame */
580@@ -293,7 +323,16 @@ enum rtl_register_content {
581 TBINwComplete = 0x01000000,
582
583 /* CPlusCmd p.31 */
584- PktCntrDisable = (1 << 7), // 8168
585+ EnableBist = (1 << 15), // 8168 8101
586+ Mac_dbgo_oe = (1 << 14), // 8168 8101
587+ Normal_mode = (1 << 13), // unused
588+ Force_half_dup = (1 << 12), // 8168 8101
589+ Force_rxflow_en = (1 << 11), // 8168 8101
590+ Force_txflow_en = (1 << 10), // 8168 8101
591+ Cxpl_dbg_sel = (1 << 9), // 8168 8101
592+ ASF = (1 << 8), // 8168 8101
593+ PktCntrDisable = (1 << 7), // 8168 8101
594+ Mac_dbgo_sel = 0x001c, // 8168
595 RxVlan = (1 << 6),
596 RxChkSum = (1 << 5),
597 PCIDAC = (1 << 4),
598--
5991.5.3.3
600
601From 61650c9e3d637b0990d9f26b1421ac4b55f5c744 Mon Sep 17 00:00:00 2001
602From: Francois Romieu <romieu@fr.zoreil.com>
603Date: Sat, 2 Aug 2008 20:44:13 +0200
604Subject: [PATCH] r8169: add hw start helpers for the 8168 and the 8101
605
606This commit triggers three 'defined but not used' warnings but
607I prefer avoiding to tie these helpers to a specific change in
608the hw start sequences of the 8168 or of the 8101.
609
610Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
611Cc: Edward Hsu <edward_hsu@realtek.com.tw>
612---
613 drivers/net/r8169.c | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++
614 1 files changed, 96 insertions(+), 0 deletions(-)
615
616diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
617index 0b8db03..52eba5c 100644
618--- a/drivers/net/r8169.c
619+++ b/drivers/net/r8169.c
620@@ -526,6 +526,11 @@ static int mdio_read(void __iomem *ioaddr, int reg_addr)
621 return value;
622 }
623
624+static void mdio_patch(void __iomem *ioaddr, int reg_addr, int value)
625+{
626+ mdio_write(ioaddr, reg_addr, mdio_read(ioaddr, reg_addr) | value);
627+}
628+
629 static void rtl_mdio_write(struct net_device *dev, int phy_id, int location,
630 int val)
631 {
632@@ -543,6 +548,72 @@ static int rtl_mdio_read(struct net_device *dev, int phy_id, int location)
633 return mdio_read(ioaddr, location);
634 }
635
636+static void rtl_ephy_write(void __iomem *ioaddr, int reg_addr, int value)
637+{
638+ unsigned int i;
639+
640+ RTL_W32(EPHYAR, EPHYAR_WRITE_CMD | (value & EPHYAR_DATA_MASK) |
641+ (reg_addr & EPHYAR_REG_MASK) << EPHYAR_REG_SHIFT);
642+
643+ for (i = 0; i < 100; i++) {
644+ if (!(RTL_R32(EPHYAR) & EPHYAR_FLAG))
645+ break;
646+ udelay(10);
647+ }
648+}
649+
650+static u16 rtl_ephy_read(void __iomem *ioaddr, int reg_addr)
651+{
652+ u16 value = 0xffff;
653+ unsigned int i;
654+
655+ RTL_W32(EPHYAR, (reg_addr & EPHYAR_REG_MASK) << EPHYAR_REG_SHIFT);
656+
657+ for (i = 0; i < 100; i++) {
658+ if (RTL_R32(EPHYAR) & EPHYAR_FLAG) {
659+ value = RTL_R32(EPHYAR) & EPHYAR_DATA_MASK;
660+ break;
661+ }
662+ udelay(10);
663+ }
664+
665+ return value;
666+}
667+
668+static void rtl_csi_write(void __iomem *ioaddr, int addr, int value)
669+{
670+ unsigned int i;
671+
672+ RTL_W32(CSIDR, value);
673+ RTL_W32(CSIAR, CSIAR_WRITE_CMD | (addr & CSIAR_ADDR_MASK) |
674+ CSIAR_BYTE_ENABLE << CSIAR_BYTE_ENABLE_SHIFT);
675+
676+ for (i = 0; i < 100; i++) {
677+ if (!(RTL_R32(CSIAR) & CSIAR_FLAG))
678+ break;
679+ udelay(10);
680+ }
681+}
682+
683+static u32 rtl_csi_read(void __iomem *ioaddr, int addr)
684+{
685+ u32 value = ~0x00;
686+ unsigned int i;
687+
688+ RTL_W32(CSIAR, (addr & CSIAR_ADDR_MASK) |
689+ CSIAR_BYTE_ENABLE << CSIAR_BYTE_ENABLE_SHIFT);
690+
691+ for (i = 0; i < 100; i++) {
692+ if (RTL_R32(CSIAR) & CSIAR_FLAG) {
693+ value = RTL_R32(CSIDR);
694+ break;
695+ }
696+ udelay(10);
697+ }
698+
699+ return value;
700+}
701+
702 static void rtl8169_irq_mask_and_ack(void __iomem *ioaddr)
703 {
704 RTL_W16(IntrMask, 0x0000);
705@@ -2114,6 +2185,31 @@ static void rtl_tx_performance_tweak(struct pci_dev *pdev, u16 force)
706 }
707 }
708
709+static void rtl_csi_access_enable(void __iomem *ioaddr)
710+{
711+ u32 csi;
712+
713+ csi = rtl_csi_read(ioaddr, 0x070c) & 0x00ffffff;
714+ rtl_csi_write(ioaddr, 0x070c, csi | 0x27000000);
715+}
716+
717+struct ephy_info {
718+ unsigned int offset;
719+ u16 mask;
720+ u16 bits;
721+};
722+
723+static void rtl_ephy_init(void __iomem *ioaddr, struct ephy_info *e, int len)
724+{
725+ u16 w;
726+
727+ while (len-- > 0) {
728+ w = (rtl_ephy_read(ioaddr, e->offset) & ~e->mask) | e->bits;
729+ rtl_ephy_write(ioaddr, e->offset, w);
730+ e++;
731+ }
732+}
733+
734 static void rtl_hw_start_8168(struct net_device *dev)
735 {
736 struct rtl8169_private *tp = netdev_priv(dev);
737--
7381.5.3.3
739
740From 81fbfc404f2a13646bee46fa98545c0023e3a67a Mon Sep 17 00:00:00 2001
741From: Francois Romieu <romieu@fr.zoreil.com>
742Date: Sat, 2 Aug 2008 21:08:49 +0200
743Subject: [PATCH] r8169: additional 8101 and 8102 support
744
745Signed-off-by: Ivan Vecera <ivecera@redhat.com>
746Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
747Cc: Edward Hsu <edward_hsu@realtek.com.tw>
748---
749 drivers/net/r8169.c | 124 ++++++++++++++++++++++++++++++++++++++++++++++++++-
750 1 files changed, 122 insertions(+), 2 deletions(-)
751
752diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
753index 52eba5c..f28c202 100644
754--- a/drivers/net/r8169.c
755+++ b/drivers/net/r8169.c
756@@ -96,6 +96,10 @@ enum mac_version {
757 RTL_GIGA_MAC_VER_04 = 0x04, // 8169SB
758 RTL_GIGA_MAC_VER_05 = 0x05, // 8110SCd
759 RTL_GIGA_MAC_VER_06 = 0x06, // 8110SCe
760+ RTL_GIGA_MAC_VER_07 = 0x07, // 8102e
761+ RTL_GIGA_MAC_VER_08 = 0x08, // 8102e
762+ RTL_GIGA_MAC_VER_09 = 0x09, // 8102e
763+ RTL_GIGA_MAC_VER_10 = 0x0a, // 8101e
764 RTL_GIGA_MAC_VER_11 = 0x0b, // 8168Bb
765 RTL_GIGA_MAC_VER_12 = 0x0c, // 8168Be
766 RTL_GIGA_MAC_VER_13 = 0x0d, // 8101Eb
767@@ -122,6 +126,10 @@ static const struct {
768 _R("RTL8169sb/8110sb", RTL_GIGA_MAC_VER_04, 0xff7e1880), // 8169SB
769 _R("RTL8169sc/8110sc", RTL_GIGA_MAC_VER_05, 0xff7e1880), // 8110SCd
770 _R("RTL8169sc/8110sc", RTL_GIGA_MAC_VER_06, 0xff7e1880), // 8110SCe
771+ _R("RTL8102e", RTL_GIGA_MAC_VER_07, 0xff7e1880), // PCI-E
772+ _R("RTL8102e", RTL_GIGA_MAC_VER_08, 0xff7e1880), // PCI-E
773+ _R("RTL8102e", RTL_GIGA_MAC_VER_09, 0xff7e1880), // PCI-E
774+ _R("RTL8101e", RTL_GIGA_MAC_VER_10, 0xff7e1880), // PCI-E
775 _R("RTL8168b/8111b", RTL_GIGA_MAC_VER_11, 0xff7e1880), // PCI-E
776 _R("RTL8168b/8111b", RTL_GIGA_MAC_VER_12, 0xff7e1880), // PCI-E
777 _R("RTL8101e", RTL_GIGA_MAC_VER_13, 0xff7e1880), // PCI-E 8139
778@@ -837,8 +845,12 @@ static int rtl8169_set_speed_xmii(struct net_device *dev,
779 }
780 }
781
782- /* The 8100e/8101e do Fast Ethernet only. */
783- if ((tp->mac_version == RTL_GIGA_MAC_VER_13) ||
784+ /* The 8100e/8101e/8102e do Fast Ethernet only. */
785+ if ((tp->mac_version == RTL_GIGA_MAC_VER_07) ||
786+ (tp->mac_version == RTL_GIGA_MAC_VER_08) ||
787+ (tp->mac_version == RTL_GIGA_MAC_VER_09) ||
788+ (tp->mac_version == RTL_GIGA_MAC_VER_10) ||
789+ (tp->mac_version == RTL_GIGA_MAC_VER_13) ||
790 (tp->mac_version == RTL_GIGA_MAC_VER_14) ||
791 (tp->mac_version == RTL_GIGA_MAC_VER_15) ||
792 (tp->mac_version == RTL_GIGA_MAC_VER_16)) {
793@@ -1212,8 +1224,17 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp,
794 { 0x7c800000, 0x30000000, RTL_GIGA_MAC_VER_11 },
795
796 /* 8101 family. */
797+ { 0x7cf00000, 0x34a00000, RTL_GIGA_MAC_VER_09 },
798+ { 0x7cf00000, 0x24a00000, RTL_GIGA_MAC_VER_09 },
799+ { 0x7cf00000, 0x34900000, RTL_GIGA_MAC_VER_08 },
800+ { 0x7cf00000, 0x24900000, RTL_GIGA_MAC_VER_08 },
801+ { 0x7cf00000, 0x34800000, RTL_GIGA_MAC_VER_07 },
802+ { 0x7cf00000, 0x24800000, RTL_GIGA_MAC_VER_07 },
803 { 0x7cf00000, 0x34000000, RTL_GIGA_MAC_VER_13 },
804+ { 0x7cf00000, 0x34300000, RTL_GIGA_MAC_VER_10 },
805 { 0x7cf00000, 0x34200000, RTL_GIGA_MAC_VER_16 },
806+ { 0x7c800000, 0x34800000, RTL_GIGA_MAC_VER_09 },
807+ { 0x7c800000, 0x24800000, RTL_GIGA_MAC_VER_09 },
808 { 0x7c800000, 0x34000000, RTL_GIGA_MAC_VER_16 },
809 /* FIXME: where did these entries come from ? -- FR */
810 { 0xfc800000, 0x38800000, RTL_GIGA_MAC_VER_15 },
811@@ -1375,6 +1396,22 @@ static void rtl8168cx_hw_phy_config(void __iomem *ioaddr)
812 rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
813 }
814
815+static void rtl8102e_hw_phy_config(void __iomem *ioaddr)
816+{
817+ struct phy_reg phy_reg_init[] = {
818+ { 0x1f, 0x0003 },
819+ { 0x08, 0x441d },
820+ { 0x01, 0x9100 },
821+ { 0x1f, 0x0000 }
822+ };
823+
824+ mdio_write(ioaddr, 0x1f, 0x0000);
825+ mdio_patch(ioaddr, 0x11, 1 << 12);
826+ mdio_patch(ioaddr, 0x19, 1 << 13);
827+
828+ rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
829+}
830+
831 static void rtl_hw_phy_config(struct net_device *dev)
832 {
833 struct rtl8169_private *tp = netdev_priv(dev);
834@@ -1392,6 +1429,11 @@ static void rtl_hw_phy_config(struct net_device *dev)
835 case RTL_GIGA_MAC_VER_04:
836 rtl8169sb_hw_phy_config(ioaddr);
837 break;
838+ case RTL_GIGA_MAC_VER_07:
839+ case RTL_GIGA_MAC_VER_08:
840+ case RTL_GIGA_MAC_VER_09:
841+ rtl8102e_hw_phy_config(ioaddr);
842+ break;
843 case RTL_GIGA_MAC_VER_18:
844 rtl8168cp_hw_phy_config(ioaddr);
845 break;
846@@ -2253,6 +2295,70 @@ static void rtl_hw_start_8168(struct net_device *dev)
847 RTL_W16(IntrMask, tp->intr_event);
848 }
849
850+#define R810X_CPCMD_QUIRK_MASK (\
851+ EnableBist | \
852+ Mac_dbgo_oe | \
853+ Force_half_dup | \
854+ Force_half_dup | \
855+ Force_txflow_en | \
856+ Cxpl_dbg_sel | \
857+ ASF | \
858+ PktCntrDisable | \
859+ PCIDAC | \
860+ PCIMulRW)
861+
862+static void rtl_hw_start_8102e_1(void __iomem *ioaddr, struct pci_dev *pdev)
863+{
864+ static struct ephy_info e_info_8102e_1[] = {
865+ { 0x01, 0, 0x6e65 },
866+ { 0x02, 0, 0x091f },
867+ { 0x03, 0, 0xc2f9 },
868+ { 0x06, 0, 0xafb5 },
869+ { 0x07, 0, 0x0e00 },
870+ { 0x19, 0, 0xec80 },
871+ { 0x01, 0, 0x2e65 },
872+ { 0x01, 0, 0x6e65 }
873+ };
874+ u8 cfg1;
875+
876+ rtl_csi_access_enable(ioaddr);
877+
878+ RTL_W8(DBG_REG, FIX_NAK_1);
879+
880+ rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
881+
882+ RTL_W8(Config1,
883+ LEDS1 | LEDS0 | Speed_down | MEMMAP | IOMAP | VPD | PMEnable);
884+ RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en);
885+
886+ cfg1 = RTL_R8(Config1);
887+ if ((cfg1 & LEDS0) && (cfg1 & LEDS1))
888+ RTL_W8(Config1, cfg1 & ~LEDS0);
889+
890+ RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R810X_CPCMD_QUIRK_MASK);
891+
892+ rtl_ephy_init(ioaddr, e_info_8102e_1, ARRAY_SIZE(e_info_8102e_1));
893+}
894+
895+static void rtl_hw_start_8102e_2(void __iomem *ioaddr, struct pci_dev *pdev)
896+{
897+ rtl_csi_access_enable(ioaddr);
898+
899+ rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
900+
901+ RTL_W8(Config1, MEMMAP | IOMAP | VPD | PMEnable);
902+ RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en);
903+
904+ RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R810X_CPCMD_QUIRK_MASK);
905+}
906+
907+static void rtl_hw_start_8102e_3(void __iomem *ioaddr, struct pci_dev *pdev)
908+{
909+ rtl_hw_start_8102e_2(ioaddr, pdev);
910+
911+ rtl_ephy_write(ioaddr, 0x03, 0xc2f9);
912+}
913+
914 static void rtl_hw_start_8101(struct net_device *dev)
915 {
916 struct rtl8169_private *tp = netdev_priv(dev);
917@@ -2269,6 +2375,20 @@ static void rtl_hw_start_8101(struct net_device *dev)
918 }
919 }
920
921+ switch (tp->mac_version) {
922+ case RTL_GIGA_MAC_VER_07:
923+ rtl_hw_start_8102e_1(ioaddr, pdev);
924+ break;
925+
926+ case RTL_GIGA_MAC_VER_08:
927+ rtl_hw_start_8102e_3(ioaddr, pdev);
928+ break;
929+
930+ case RTL_GIGA_MAC_VER_09:
931+ rtl_hw_start_8102e_2(ioaddr, pdev);
932+ break;
933+ }
934+
935 RTL_W8(Cfg9346, Cfg9346_Unlock);
936
937 RTL_W8(EarlyTxThres, EarlyTxThld);
938--
9391.5.3.3
940
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0042-intelfb-945gme.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0042-intelfb-945gme.patch
new file mode 100644
index 0000000000..15ebe56328
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/0042-intelfb-945gme.patch
@@ -0,0 +1,153 @@
1The following patch adds support for Intel's 945GME graphics chip to
2the intelfb driver. I have assumed that the 945GME is identical to the
3already-supported 945GM apart from its PCI IDs; this is based on a quick
4look at the X driver for these chips which seems to treat them
5identically.
6
7Signed-off-by: Phil Endecott <spam_from_intelfb@chezphil.org>
8
9---
10
11The 945GME is used in the ASUS Eee 901, and I coded this in the hope that
12I'd be able to use it to get a console at the native 1024x600 resolution
13which is not known to the BIOS. I realised too late that the intelfb
14driver does not support mode changing on laptops, so it won't be any
15use for me. But rather than throw it away I will post it here as
16essentially "untested"; maybe someone who knows more about this driver,
17and with more useful hardware to test on, can pick it up.
18
19diff --git a/Documentation/fb/intelfb.txt b/Documentation/fb/intelfb.txt
20index 27a3160..dd9e944 100644
21--- a/Documentation/fb/intelfb.txt
22+++ b/Documentation/fb/intelfb.txt
23@@ -14,6 +14,7 @@ graphics devices. These would include:
24 Intel 915GM
25 Intel 945G
26 Intel 945GM
27+ Intel 945GME
28 Intel 965G
29 Intel 965GM
30
31diff --git a/drivers/video/intelfb/intelfb.h b/drivers/video/intelfb/intelfb.h
32index 3325fbd..a50bea6 100644
33--- a/drivers/video/intelfb/intelfb.h
34+++ b/drivers/video/intelfb/intelfb.h
35@@ -12,9 +12,9 @@
36 #endif
37
38 /*** Version/name ***/
39-#define INTELFB_VERSION "0.9.5"
40+#define INTELFB_VERSION "0.9.6"
41 #define INTELFB_MODULE_NAME "intelfb"
42-#define SUPPORTED_CHIPSETS "830M/845G/852GM/855GM/865G/915G/915GM/945G/945GM/965G/965GM"
43+#define SUPPORTED_CHIPSETS "830M/845G/852GM/855GM/865G/915G/915GM/945G/945GM/945GME/965G/965GM"
44
45
46 /*** Debug/feature defines ***/
47@@ -58,6 +58,7 @@
48 #define PCI_DEVICE_ID_INTEL_915GM 0x2592
49 #define PCI_DEVICE_ID_INTEL_945G 0x2772
50 #define PCI_DEVICE_ID_INTEL_945GM 0x27A2
51+#define PCI_DEVICE_ID_INTEL_945GME 0x27AE
52 #define PCI_DEVICE_ID_INTEL_965G 0x29A2
53 #define PCI_DEVICE_ID_INTEL_965GM 0x2A02
54
55@@ -160,6 +161,7 @@ enum intel_chips {
56 INTEL_915GM,
57 INTEL_945G,
58 INTEL_945GM,
59+ INTEL_945GME,
60 INTEL_965G,
61 INTEL_965GM,
62 };
63@@ -363,6 +365,7 @@ struct intelfb_info {
64 ((dinfo)->chipset == INTEL_915GM) || \
65 ((dinfo)->chipset == INTEL_945G) || \
66 ((dinfo)->chipset == INTEL_945GM) || \
67+ ((dinfo)->chipset == INTEL_945GME) || \
68 ((dinfo)->chipset == INTEL_965G) || \
69 ((dinfo)->chipset == INTEL_965GM))
70
71diff --git a/drivers/video/intelfb/intelfb_i2c.c b/drivers/video/intelfb/intelfb_i2c.c
72index fcf9fad..5d896b8 100644
73--- a/drivers/video/intelfb/intelfb_i2c.c
74+++ b/drivers/video/intelfb/intelfb_i2c.c
75@@ -171,6 +171,7 @@ void intelfb_create_i2c_busses(struct intelfb_info *dinfo)
76 /* has some LVDS + tv-out */
77 case INTEL_945G:
78 case INTEL_945GM:
79+ case INTEL_945GME:
80 case INTEL_965G:
81 case INTEL_965GM:
82 /* SDVO ports have a single control bus - 2 devices */
83diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c
84index e44303f..a09e236 100644
85--- a/drivers/video/intelfb/intelfbdrv.c
86+++ b/drivers/video/intelfb/intelfbdrv.c
87@@ -2,7 +2,7 @@
88 * intelfb
89 *
90 * Linux framebuffer driver for Intel(R) 830M/845G/852GM/855GM/865G/915G/915GM/
91- * 945G/945GM/965G/965GM integrated graphics chips.
92+ * 945G/945GM/945GME/965G/965GM integrated graphics chips.
93 *
94 * Copyright © 2002, 2003 David Dawes <dawes@xfree86.org>
95 * 2004 Sylvain Meyer
96@@ -102,6 +102,9 @@
97 *
98 * 04/2008 - Version 0.9.5
99 * Add support for 965G/965GM. (Maik Broemme <mbroemme@plusserver.de>)
100+ *
101+ * 08/2008 - Version 0.9.6
102+ * Add support for 945GME. (Phil Endecott <spam_from_intelfb@chezphil.org>)
103 */
104
105 #include <linux/module.h>
106@@ -183,6 +186,7 @@ static struct pci_device_id intelfb_pci_table[] __devinitdata = {
107 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_915GM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_915GM },
108 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_945G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_945G },
109 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_945GM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_945GM },
110+ { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_945GME, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_945GME },
111 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_965G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_965G },
112 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_965GM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_965GM },
113 { 0, }
114@@ -555,6 +559,7 @@ static int __devinit intelfb_pci_register(struct pci_dev *pdev,
115 (ent->device == PCI_DEVICE_ID_INTEL_915GM) ||
116 (ent->device == PCI_DEVICE_ID_INTEL_945G) ||
117 (ent->device == PCI_DEVICE_ID_INTEL_945GM) ||
118+ (ent->device == PCI_DEVICE_ID_INTEL_945GME) ||
119 (ent->device == PCI_DEVICE_ID_INTEL_965G) ||
120 (ent->device == PCI_DEVICE_ID_INTEL_965GM)) {
121
122diff --git a/drivers/video/intelfb/intelfbhw.c b/drivers/video/intelfb/intelfbhw.c
123index 8e6d6a4..8b26b27 100644
124--- a/drivers/video/intelfb/intelfbhw.c
125+++ b/drivers/video/intelfb/intelfbhw.c
126@@ -143,6 +143,12 @@ int intelfbhw_get_chipset(struct pci_dev *pdev, struct intelfb_info *dinfo)
127 dinfo->mobile = 1;
128 dinfo->pll_index = PLLS_I9xx;
129 return 0;
130+ case PCI_DEVICE_ID_INTEL_945GME:
131+ dinfo->name = "Intel(R) 945GME";
132+ dinfo->chipset = INTEL_945GME;
133+ dinfo->mobile = 1;
134+ dinfo->pll_index = PLLS_I9xx;
135+ return 0;
136 case PCI_DEVICE_ID_INTEL_965G:
137 dinfo->name = "Intel(R) 965G";
138 dinfo->chipset = INTEL_965G;
139@@ -186,6 +192,7 @@ int intelfbhw_get_memory(struct pci_dev *pdev, int *aperture_size,
140 case PCI_DEVICE_ID_INTEL_915GM:
141 case PCI_DEVICE_ID_INTEL_945G:
142 case PCI_DEVICE_ID_INTEL_945GM:
143+ case PCI_DEVICE_ID_INTEL_945GME:
144 case PCI_DEVICE_ID_INTEL_965G:
145 case PCI_DEVICE_ID_INTEL_965GM:
146 /* 915, 945 and 965 chipsets support a 256MB aperture.
147
148
149--
150To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
151the body of a message to majordomo@vger.kernel.org
152More majordomo info at http://vger.kernel.org/majordomo-info.html
153Please read the FAQ at http://www.tux.org/lkml/ \ No newline at end of file
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/defconfig-eee901 b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/defconfig-eee901
new file mode 100644
index 0000000000..b2b3cb0c3e
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/defconfig-eee901
@@ -0,0 +1,2424 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.27-rc6
4# Thu Oct 9 20:10:11 2008
5#
6# CONFIG_64BIT is not set
7CONFIG_X86_32=y
8# CONFIG_X86_64 is not set
9CONFIG_X86=y
10CONFIG_ARCH_DEFCONFIG="arch/x86/configs/i386_defconfig"
11# CONFIG_GENERIC_LOCKBREAK is not set
12CONFIG_GENERIC_TIME=y
13CONFIG_GENERIC_CMOS_UPDATE=y
14CONFIG_CLOCKSOURCE_WATCHDOG=y
15CONFIG_GENERIC_CLOCKEVENTS=y
16CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
17CONFIG_LOCKDEP_SUPPORT=y
18CONFIG_STACKTRACE_SUPPORT=y
19CONFIG_HAVE_LATENCYTOP_SUPPORT=y
20CONFIG_FAST_CMPXCHG_LOCAL=y
21CONFIG_MMU=y
22CONFIG_ZONE_DMA=y
23CONFIG_GENERIC_ISA_DMA=y
24CONFIG_GENERIC_IOMAP=y
25CONFIG_GENERIC_BUG=y
26CONFIG_GENERIC_HWEIGHT=y
27# CONFIG_GENERIC_GPIO is not set
28CONFIG_ARCH_MAY_HAVE_PC_FDC=y
29# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
30CONFIG_RWSEM_XCHGADD_ALGORITHM=y
31# CONFIG_ARCH_HAS_ILOG2_U32 is not set
32# CONFIG_ARCH_HAS_ILOG2_U64 is not set
33CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
34CONFIG_GENERIC_CALIBRATE_DELAY=y
35# CONFIG_GENERIC_TIME_VSYSCALL is not set
36CONFIG_ARCH_HAS_CPU_RELAX=y
37CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y
38CONFIG_HAVE_SETUP_PER_CPU_AREA=y
39# CONFIG_HAVE_CPUMASK_OF_CPU_MAP is not set
40CONFIG_ARCH_HIBERNATION_POSSIBLE=y
41CONFIG_ARCH_SUSPEND_POSSIBLE=y
42# CONFIG_ZONE_DMA32 is not set
43CONFIG_ARCH_POPULATES_NODE_MAP=y
44# CONFIG_AUDIT_ARCH is not set
45CONFIG_ARCH_SUPPORTS_AOUT=y
46CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING=y
47CONFIG_GENERIC_HARDIRQS=y
48CONFIG_GENERIC_IRQ_PROBE=y
49CONFIG_GENERIC_PENDING_IRQ=y
50CONFIG_X86_SMP=y
51CONFIG_X86_32_SMP=y
52CONFIG_X86_HT=y
53CONFIG_X86_BIOS_REBOOT=y
54CONFIG_X86_TRAMPOLINE=y
55CONFIG_KTIME_SCALAR=y
56CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
57
58#
59# General setup
60#
61CONFIG_EXPERIMENTAL=y
62CONFIG_LOCK_KERNEL=y
63CONFIG_INIT_ENV_ARG_LIMIT=32
64CONFIG_LOCALVERSION="-eee901"
65# CONFIG_LOCALVERSION_AUTO is not set
66CONFIG_SWAP=y
67CONFIG_SYSVIPC=y
68CONFIG_SYSVIPC_SYSCTL=y
69CONFIG_POSIX_MQUEUE=y
70CONFIG_BSD_PROCESS_ACCT=y
71CONFIG_BSD_PROCESS_ACCT_V3=y
72CONFIG_TASKSTATS=y
73CONFIG_TASK_DELAY_ACCT=y
74CONFIG_TASK_XACCT=y
75CONFIG_TASK_IO_ACCOUNTING=y
76CONFIG_AUDIT=y
77CONFIG_AUDITSYSCALL=y
78CONFIG_AUDIT_TREE=y
79CONFIG_IKCONFIG=y
80CONFIG_IKCONFIG_PROC=y
81CONFIG_LOG_BUF_SHIFT=17
82# CONFIG_CGROUPS is not set
83CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y
84# CONFIG_GROUP_SCHED is not set
85# CONFIG_SYSFS_DEPRECATED_V2 is not set
86CONFIG_RELAY=y
87CONFIG_NAMESPACES=y
88# CONFIG_UTS_NS is not set
89# CONFIG_IPC_NS is not set
90CONFIG_USER_NS=y
91# CONFIG_PID_NS is not set
92CONFIG_BLK_DEV_INITRD=y
93CONFIG_INITRAMFS_SOURCE=""
94CONFIG_CC_OPTIMIZE_FOR_SIZE=y
95CONFIG_FASTBOOT=y
96CONFIG_SYSCTL=y
97# CONFIG_EMBEDDED is not set
98CONFIG_UID16=y
99CONFIG_SYSCTL_SYSCALL=y
100CONFIG_KALLSYMS=y
101CONFIG_KALLSYMS_ALL=y
102CONFIG_KALLSYMS_EXTRA_PASS=y
103CONFIG_HOTPLUG=y
104CONFIG_PRINTK=y
105CONFIG_BUG=y
106CONFIG_ELF_CORE=y
107CONFIG_PCSPKR_PLATFORM=y
108# CONFIG_COMPAT_BRK is not set
109CONFIG_BASE_FULL=y
110CONFIG_FUTEX=y
111CONFIG_ANON_INODES=y
112CONFIG_EPOLL=y
113CONFIG_SIGNALFD=y
114CONFIG_TIMERFD=y
115CONFIG_EVENTFD=y
116CONFIG_SHMEM=y
117CONFIG_VM_EVENT_COUNTERS=y
118CONFIG_SLAB=y
119# CONFIG_SLUB is not set
120# CONFIG_SLOB is not set
121CONFIG_PROFILING=y
122# CONFIG_MARKERS is not set
123# CONFIG_OPROFILE is not set
124CONFIG_HAVE_OPROFILE=y
125# CONFIG_KPROBES is not set
126CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
127CONFIG_HAVE_IOREMAP_PROT=y
128CONFIG_HAVE_KPROBES=y
129CONFIG_HAVE_KRETPROBES=y
130# CONFIG_HAVE_ARCH_TRACEHOOK is not set
131# CONFIG_HAVE_DMA_ATTRS is not set
132CONFIG_USE_GENERIC_SMP_HELPERS=y
133# CONFIG_HAVE_CLK is not set
134CONFIG_PROC_PAGE_MONITOR=y
135CONFIG_HAVE_GENERIC_DMA_COHERENT=y
136CONFIG_SLABINFO=y
137CONFIG_RT_MUTEXES=y
138# CONFIG_TINY_SHMEM is not set
139CONFIG_BASE_SMALL=0
140CONFIG_MODULES=y
141# CONFIG_MODULE_FORCE_LOAD is not set
142CONFIG_MODULE_UNLOAD=y
143# CONFIG_MODULE_FORCE_UNLOAD is not set
144# CONFIG_MODVERSIONS is not set
145# CONFIG_MODULE_SRCVERSION_ALL is not set
146CONFIG_KMOD=y
147CONFIG_STOP_MACHINE=y
148CONFIG_BLOCK=y
149# CONFIG_LBD is not set
150CONFIG_BLK_DEV_IO_TRACE=y
151# CONFIG_LSF is not set
152CONFIG_BLK_DEV_BSG=y
153# CONFIG_BLK_DEV_INTEGRITY is not set
154
155#
156# IO Schedulers
157#
158CONFIG_IOSCHED_NOOP=y
159# CONFIG_IOSCHED_AS is not set
160# CONFIG_IOSCHED_DEADLINE is not set
161CONFIG_IOSCHED_CFQ=y
162# CONFIG_DEFAULT_AS is not set
163# CONFIG_DEFAULT_DEADLINE is not set
164CONFIG_DEFAULT_CFQ=y
165# CONFIG_DEFAULT_NOOP is not set
166CONFIG_DEFAULT_IOSCHED="cfq"
167CONFIG_CLASSIC_RCU=y
168
169#
170# Processor type and features
171#
172CONFIG_TICK_ONESHOT=y
173CONFIG_NO_HZ=y
174CONFIG_HIGH_RES_TIMERS=y
175CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
176CONFIG_SMP=y
177CONFIG_X86_FIND_SMP_CONFIG=y
178CONFIG_X86_MPPARSE=y
179CONFIG_X86_PC=y
180# CONFIG_X86_ELAN is not set
181# CONFIG_X86_VOYAGER is not set
182# CONFIG_X86_GENERICARCH is not set
183# CONFIG_X86_VSMP is not set
184# CONFIG_X86_RDC321X is not set
185CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
186# CONFIG_PARAVIRT_GUEST is not set
187# CONFIG_MEMTEST is not set
188# CONFIG_M386 is not set
189# CONFIG_M486 is not set
190# CONFIG_M586 is not set
191# CONFIG_M586TSC is not set
192# CONFIG_M586MMX is not set
193CONFIG_M686=y
194# CONFIG_MPENTIUMII is not set
195# CONFIG_MPENTIUMIII is not set
196# CONFIG_MPENTIUMM is not set
197# CONFIG_MPENTIUM4 is not set
198# CONFIG_MK6 is not set
199# CONFIG_MK7 is not set
200# CONFIG_MK8 is not set
201# CONFIG_MCRUSOE is not set
202# CONFIG_MEFFICEON is not set
203# CONFIG_MWINCHIPC6 is not set
204# CONFIG_MWINCHIP2 is not set
205# CONFIG_MWINCHIP3D is not set
206# CONFIG_MGEODEGX1 is not set
207# CONFIG_MGEODE_LX is not set
208# CONFIG_MCYRIXIII is not set
209# CONFIG_MVIAC3_2 is not set
210# CONFIG_MVIAC7 is not set
211# CONFIG_MPSC is not set
212# CONFIG_MCORE2 is not set
213# CONFIG_GENERIC_CPU is not set
214# CONFIG_X86_GENERIC is not set
215CONFIG_X86_CPU=y
216CONFIG_X86_CMPXCHG=y
217CONFIG_X86_L1_CACHE_SHIFT=5
218CONFIG_X86_XADD=y
219# CONFIG_X86_PPRO_FENCE is not set
220CONFIG_X86_WP_WORKS_OK=y
221CONFIG_X86_INVLPG=y
222CONFIG_X86_BSWAP=y
223CONFIG_X86_POPAD_OK=y
224CONFIG_X86_USE_PPRO_CHECKSUM=y
225CONFIG_X86_TSC=y
226CONFIG_X86_CMOV=y
227CONFIG_X86_MINIMUM_CPU_FAMILY=4
228CONFIG_X86_DEBUGCTLMSR=y
229CONFIG_HPET_TIMER=y
230CONFIG_HPET_EMULATE_RTC=y
231CONFIG_DMI=y
232# CONFIG_IOMMU_HELPER is not set
233CONFIG_NR_CPUS=2
234CONFIG_SCHED_SMT=y
235CONFIG_SCHED_MC=y
236# CONFIG_PREEMPT_NONE is not set
237CONFIG_PREEMPT_VOLUNTARY=y
238# CONFIG_PREEMPT is not set
239CONFIG_X86_LOCAL_APIC=y
240CONFIG_X86_IO_APIC=y
241CONFIG_X86_MCE=y
242# CONFIG_X86_MCE_NONFATAL is not set
243# CONFIG_X86_MCE_P4THERMAL is not set
244CONFIG_VM86=y
245# CONFIG_TOSHIBA is not set
246# CONFIG_I8K is not set
247# CONFIG_X86_REBOOTFIXUPS is not set
248CONFIG_MICROCODE=y
249CONFIG_MICROCODE_OLD_INTERFACE=y
250CONFIG_X86_MSR=y
251CONFIG_X86_CPUID=y
252# CONFIG_NOHIGHMEM is not set
253CONFIG_HIGHMEM4G=y
254# CONFIG_HIGHMEM64G is not set
255CONFIG_PAGE_OFFSET=0xC0000000
256CONFIG_HIGHMEM=y
257CONFIG_NEED_NODE_MEMMAP_SIZE=y
258CONFIG_ARCH_FLATMEM_ENABLE=y
259CONFIG_ARCH_SPARSEMEM_ENABLE=y
260CONFIG_ARCH_SELECT_MEMORY_MODEL=y
261CONFIG_SELECT_MEMORY_MODEL=y
262# CONFIG_FLATMEM_MANUAL is not set
263# CONFIG_DISCONTIGMEM_MANUAL is not set
264CONFIG_SPARSEMEM_MANUAL=y
265CONFIG_SPARSEMEM=y
266CONFIG_HAVE_MEMORY_PRESENT=y
267CONFIG_SPARSEMEM_STATIC=y
268# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
269
270#
271# Memory hotplug is currently incompatible with Software Suspend
272#
273CONFIG_PAGEFLAGS_EXTENDED=y
274CONFIG_SPLIT_PTLOCK_CPUS=4
275CONFIG_RESOURCES_64BIT=y
276CONFIG_ZONE_DMA_FLAG=1
277CONFIG_BOUNCE=y
278CONFIG_VIRT_TO_BUS=y
279# CONFIG_HIGHPTE is not set
280# CONFIG_MATH_EMULATION is not set
281CONFIG_MTRR=y
282# CONFIG_MTRR_SANITIZER is not set
283# CONFIG_X86_PAT is not set
284# CONFIG_EFI is not set
285# CONFIG_IRQBALANCE is not set
286# CONFIG_SECCOMP is not set
287# CONFIG_HZ_100 is not set
288# CONFIG_HZ_250 is not set
289# CONFIG_HZ_300 is not set
290CONFIG_HZ_1000=y
291CONFIG_HZ=1000
292CONFIG_SCHED_HRTICK=y
293CONFIG_KEXEC=y
294CONFIG_CRASH_DUMP=y
295# CONFIG_KEXEC_JUMP is not set
296CONFIG_PHYSICAL_START=0x400000
297CONFIG_RELOCATABLE=y
298CONFIG_PHYSICAL_ALIGN=0x200000
299CONFIG_HOTPLUG_CPU=y
300CONFIG_COMPAT_VDSO=y
301CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
302
303#
304# Power management options
305#
306CONFIG_PM=y
307CONFIG_PM_DEBUG=y
308# CONFIG_PM_VERBOSE is not set
309CONFIG_CAN_PM_TRACE=y
310CONFIG_PM_TRACE=y
311CONFIG_PM_TRACE_RTC=y
312CONFIG_PM_SLEEP_SMP=y
313CONFIG_PM_SLEEP=y
314CONFIG_SUSPEND=y
315# CONFIG_PM_TEST_SUSPEND is not set
316CONFIG_SUSPEND_FREEZER=y
317CONFIG_HIBERNATION=y
318CONFIG_PM_STD_PARTITION=""
319CONFIG_ACPI=y
320CONFIG_ACPI_SLEEP=y
321CONFIG_ACPI_PROCFS=y
322CONFIG_ACPI_PROCFS_POWER=y
323CONFIG_ACPI_SYSFS_POWER=y
324CONFIG_ACPI_PROC_EVENT=y
325CONFIG_ACPI_AC=y
326CONFIG_ACPI_BATTERY=m
327CONFIG_ACPI_BUTTON=y
328CONFIG_ACPI_VIDEO=y
329CONFIG_ACPI_FAN=y
330CONFIG_ACPI_DOCK=y
331# CONFIG_ACPI_BAY is not set
332CONFIG_ACPI_PROCESSOR=y
333CONFIG_ACPI_HOTPLUG_CPU=y
334CONFIG_ACPI_THERMAL=y
335CONFIG_ACPI_WMI=m
336CONFIG_ACPI_ASUS=y
337# CONFIG_ACPI_TOSHIBA is not set
338# CONFIG_ACPI_CUSTOM_DSDT is not set
339CONFIG_ACPI_BLACKLIST_YEAR=0
340# CONFIG_ACPI_DEBUG is not set
341CONFIG_ACPI_EC=y
342# CONFIG_ACPI_PCI_SLOT is not set
343CONFIG_ACPI_POWER=y
344CONFIG_ACPI_SYSTEM=y
345CONFIG_X86_PM_TIMER=y
346CONFIG_ACPI_CONTAINER=y
347CONFIG_ACPI_SBS=m
348# CONFIG_APM is not set
349
350#
351# CPU Frequency scaling
352#
353CONFIG_CPU_FREQ=y
354CONFIG_CPU_FREQ_TABLE=y
355CONFIG_CPU_FREQ_DEBUG=y
356CONFIG_CPU_FREQ_STAT=m
357CONFIG_CPU_FREQ_STAT_DETAILS=y
358CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
359# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
360# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
361# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
362# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
363CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
364# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
365CONFIG_CPU_FREQ_GOV_USERSPACE=y
366CONFIG_CPU_FREQ_GOV_ONDEMAND=y
367# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
368
369#
370# CPUFreq processor drivers
371#
372CONFIG_X86_ACPI_CPUFREQ=y
373# CONFIG_X86_POWERNOW_K6 is not set
374# CONFIG_X86_POWERNOW_K7 is not set
375# CONFIG_X86_POWERNOW_K8 is not set
376# CONFIG_X86_GX_SUSPMOD is not set
377# CONFIG_X86_SPEEDSTEP_CENTRINO is not set
378# CONFIG_X86_SPEEDSTEP_ICH is not set
379# CONFIG_X86_SPEEDSTEP_SMI is not set
380# CONFIG_X86_P4_CLOCKMOD is not set
381# CONFIG_X86_CPUFREQ_NFORCE2 is not set
382# CONFIG_X86_LONGRUN is not set
383# CONFIG_X86_LONGHAUL is not set
384# CONFIG_X86_E_POWERSAVER is not set
385
386#
387# shared options
388#
389# CONFIG_X86_ACPI_CPUFREQ_PROC_INTF is not set
390# CONFIG_X86_SPEEDSTEP_LIB is not set
391CONFIG_CPU_IDLE=y
392CONFIG_CPU_IDLE_GOV_LADDER=y
393CONFIG_CPU_IDLE_GOV_MENU=y
394
395#
396# Bus options (PCI etc.)
397#
398CONFIG_PCI=y
399# CONFIG_PCI_GOBIOS is not set
400# CONFIG_PCI_GOMMCONFIG is not set
401# CONFIG_PCI_GODIRECT is not set
402# CONFIG_PCI_GOOLPC is not set
403CONFIG_PCI_GOANY=y
404CONFIG_PCI_BIOS=y
405CONFIG_PCI_DIRECT=y
406CONFIG_PCI_MMCONFIG=y
407CONFIG_PCI_DOMAINS=y
408CONFIG_PCIEPORTBUS=y
409CONFIG_PCIEAER=y
410CONFIG_PCIEASPM=y
411# CONFIG_PCIEASPM_DEBUG is not set
412CONFIG_ARCH_SUPPORTS_MSI=y
413CONFIG_PCI_MSI=y
414CONFIG_PCI_LEGACY=y
415# CONFIG_PCI_DEBUG is not set
416CONFIG_HT_IRQ=y
417CONFIG_ISA_DMA_API=y
418# CONFIG_ISA is not set
419# CONFIG_MCA is not set
420# CONFIG_SCx200 is not set
421# CONFIG_OLPC is not set
422CONFIG_K8_NB=y
423# CONFIG_PCCARD is not set
424# CONFIG_HOTPLUG_PCI is not set
425
426#
427# Executable file formats / Emulations
428#
429CONFIG_BINFMT_ELF=y
430# CONFIG_BINFMT_AOUT is not set
431CONFIG_BINFMT_MISC=y
432CONFIG_NET=y
433
434#
435# Networking options
436#
437CONFIG_PACKET=y
438CONFIG_PACKET_MMAP=y
439CONFIG_UNIX=y
440CONFIG_XFRM=y
441CONFIG_XFRM_USER=y
442CONFIG_XFRM_SUB_POLICY=y
443CONFIG_XFRM_MIGRATE=y
444CONFIG_XFRM_STATISTICS=y
445CONFIG_XFRM_IPCOMP=m
446CONFIG_NET_KEY=m
447CONFIG_NET_KEY_MIGRATE=y
448CONFIG_INET=y
449CONFIG_IP_MULTICAST=y
450# CONFIG_IP_ADVANCED_ROUTER is not set
451CONFIG_IP_FIB_HASH=y
452CONFIG_IP_PNP=y
453CONFIG_IP_PNP_DHCP=y
454# CONFIG_IP_PNP_BOOTP is not set
455# CONFIG_IP_PNP_RARP is not set
456# CONFIG_NET_IPIP is not set
457# CONFIG_NET_IPGRE is not set
458CONFIG_IP_MROUTE=y
459CONFIG_IP_PIMSM_V1=y
460CONFIG_IP_PIMSM_V2=y
461# CONFIG_ARPD is not set
462CONFIG_SYN_COOKIES=y
463CONFIG_INET_AH=m
464CONFIG_INET_ESP=m
465CONFIG_INET_IPCOMP=m
466CONFIG_INET_XFRM_TUNNEL=m
467CONFIG_INET_TUNNEL=m
468CONFIG_INET_XFRM_MODE_TRANSPORT=m
469CONFIG_INET_XFRM_MODE_TUNNEL=m
470CONFIG_INET_XFRM_MODE_BEET=m
471CONFIG_INET_LRO=y
472CONFIG_INET_DIAG=m
473CONFIG_INET_TCP_DIAG=m
474CONFIG_TCP_CONG_ADVANCED=y
475CONFIG_TCP_CONG_BIC=m
476CONFIG_TCP_CONG_CUBIC=y
477# CONFIG_TCP_CONG_WESTWOOD is not set
478# CONFIG_TCP_CONG_HTCP is not set
479# CONFIG_TCP_CONG_HSTCP is not set
480# CONFIG_TCP_CONG_HYBLA is not set
481# CONFIG_TCP_CONG_VEGAS is not set
482# CONFIG_TCP_CONG_SCALABLE is not set
483# CONFIG_TCP_CONG_LP is not set
484# CONFIG_TCP_CONG_VENO is not set
485# CONFIG_TCP_CONG_YEAH is not set
486# CONFIG_TCP_CONG_ILLINOIS is not set
487# CONFIG_DEFAULT_BIC is not set
488CONFIG_DEFAULT_CUBIC=y
489# CONFIG_DEFAULT_HTCP is not set
490# CONFIG_DEFAULT_VEGAS is not set
491# CONFIG_DEFAULT_WESTWOOD is not set
492# CONFIG_DEFAULT_RENO is not set
493CONFIG_DEFAULT_TCP_CONG="cubic"
494CONFIG_TCP_MD5SIG=y
495# CONFIG_IP_VS is not set
496CONFIG_IPV6=y
497CONFIG_IPV6_PRIVACY=y
498CONFIG_IPV6_ROUTER_PREF=y
499CONFIG_IPV6_ROUTE_INFO=y
500CONFIG_IPV6_OPTIMISTIC_DAD=y
501CONFIG_INET6_AH=m
502CONFIG_INET6_ESP=m
503CONFIG_INET6_IPCOMP=m
504CONFIG_IPV6_MIP6=m
505CONFIG_INET6_XFRM_TUNNEL=m
506CONFIG_INET6_TUNNEL=m
507CONFIG_INET6_XFRM_MODE_TRANSPORT=m
508CONFIG_INET6_XFRM_MODE_TUNNEL=m
509CONFIG_INET6_XFRM_MODE_BEET=m
510CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
511CONFIG_IPV6_SIT=m
512CONFIG_IPV6_NDISC_NODETYPE=y
513CONFIG_IPV6_TUNNEL=m
514CONFIG_IPV6_MULTIPLE_TABLES=y
515CONFIG_IPV6_SUBTREES=y
516# CONFIG_IPV6_MROUTE is not set
517CONFIG_NETLABEL=y
518CONFIG_NETWORK_SECMARK=y
519CONFIG_NETFILTER=y
520# CONFIG_NETFILTER_DEBUG is not set
521CONFIG_NETFILTER_ADVANCED=y
522
523#
524# Core Netfilter Configuration
525#
526CONFIG_NETFILTER_NETLINK=m
527CONFIG_NETFILTER_NETLINK_QUEUE=m
528CONFIG_NETFILTER_NETLINK_LOG=m
529CONFIG_NF_CONNTRACK=y
530CONFIG_NF_CT_ACCT=y
531CONFIG_NF_CONNTRACK_MARK=y
532CONFIG_NF_CONNTRACK_SECMARK=y
533CONFIG_NF_CONNTRACK_EVENTS=y
534# CONFIG_NF_CT_PROTO_DCCP is not set
535CONFIG_NF_CT_PROTO_GRE=m
536CONFIG_NF_CT_PROTO_SCTP=m
537CONFIG_NF_CT_PROTO_UDPLITE=m
538CONFIG_NF_CONNTRACK_AMANDA=m
539CONFIG_NF_CONNTRACK_FTP=m
540CONFIG_NF_CONNTRACK_H323=m
541CONFIG_NF_CONNTRACK_IRC=m
542CONFIG_NF_CONNTRACK_NETBIOS_NS=m
543CONFIG_NF_CONNTRACK_PPTP=m
544CONFIG_NF_CONNTRACK_SANE=m
545CONFIG_NF_CONNTRACK_SIP=m
546CONFIG_NF_CONNTRACK_TFTP=m
547CONFIG_NF_CT_NETLINK=m
548CONFIG_NETFILTER_XTABLES=y
549CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
550CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
551CONFIG_NETFILTER_XT_TARGET_DSCP=m
552CONFIG_NETFILTER_XT_TARGET_MARK=m
553CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
554CONFIG_NETFILTER_XT_TARGET_NFLOG=m
555CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
556CONFIG_NETFILTER_XT_TARGET_RATEEST=m
557CONFIG_NETFILTER_XT_TARGET_TRACE=m
558CONFIG_NETFILTER_XT_TARGET_SECMARK=m
559CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
560CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
561CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
562CONFIG_NETFILTER_XT_MATCH_COMMENT=m
563CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
564CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
565CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
566CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
567# CONFIG_NETFILTER_XT_MATCH_DCCP is not set
568CONFIG_NETFILTER_XT_MATCH_DSCP=m
569CONFIG_NETFILTER_XT_MATCH_ESP=m
570CONFIG_NETFILTER_XT_MATCH_HELPER=m
571CONFIG_NETFILTER_XT_MATCH_IPRANGE=m
572CONFIG_NETFILTER_XT_MATCH_LENGTH=m
573CONFIG_NETFILTER_XT_MATCH_LIMIT=m
574CONFIG_NETFILTER_XT_MATCH_MAC=m
575CONFIG_NETFILTER_XT_MATCH_MARK=m
576CONFIG_NETFILTER_XT_MATCH_OWNER=m
577CONFIG_NETFILTER_XT_MATCH_POLICY=m
578CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
579CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
580CONFIG_NETFILTER_XT_MATCH_QUOTA=m
581CONFIG_NETFILTER_XT_MATCH_RATEEST=m
582CONFIG_NETFILTER_XT_MATCH_REALM=m
583CONFIG_NETFILTER_XT_MATCH_SCTP=m
584CONFIG_NETFILTER_XT_MATCH_STATE=y
585CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
586CONFIG_NETFILTER_XT_MATCH_STRING=m
587CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
588CONFIG_NETFILTER_XT_MATCH_TIME=m
589CONFIG_NETFILTER_XT_MATCH_U32=m
590CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
591
592#
593# IP: Netfilter Configuration
594#
595CONFIG_NF_CONNTRACK_IPV4=y
596# CONFIG_NF_CONNTRACK_PROC_COMPAT is not set
597CONFIG_IP_NF_QUEUE=m
598CONFIG_IP_NF_IPTABLES=y
599CONFIG_IP_NF_MATCH_RECENT=m
600CONFIG_IP_NF_MATCH_ECN=m
601CONFIG_IP_NF_MATCH_AH=m
602CONFIG_IP_NF_MATCH_TTL=m
603CONFIG_IP_NF_MATCH_ADDRTYPE=m
604CONFIG_IP_NF_FILTER=y
605CONFIG_IP_NF_TARGET_REJECT=y
606CONFIG_IP_NF_TARGET_LOG=m
607CONFIG_IP_NF_TARGET_ULOG=m
608CONFIG_NF_NAT=m
609CONFIG_NF_NAT_NEEDED=y
610CONFIG_IP_NF_TARGET_MASQUERADE=m
611CONFIG_IP_NF_TARGET_REDIRECT=m
612CONFIG_IP_NF_TARGET_NETMAP=m
613CONFIG_NF_NAT_SNMP_BASIC=m
614CONFIG_NF_NAT_PROTO_GRE=m
615CONFIG_NF_NAT_PROTO_UDPLITE=m
616CONFIG_NF_NAT_PROTO_SCTP=m
617CONFIG_NF_NAT_FTP=m
618CONFIG_NF_NAT_IRC=m
619CONFIG_NF_NAT_TFTP=m
620CONFIG_NF_NAT_AMANDA=m
621CONFIG_NF_NAT_PPTP=m
622CONFIG_NF_NAT_H323=m
623CONFIG_NF_NAT_SIP=m
624CONFIG_IP_NF_MANGLE=m
625CONFIG_IP_NF_TARGET_ECN=m
626CONFIG_IP_NF_TARGET_TTL=m
627CONFIG_IP_NF_TARGET_CLUSTERIP=m
628CONFIG_IP_NF_RAW=m
629# CONFIG_IP_NF_SECURITY is not set
630CONFIG_IP_NF_ARPTABLES=m
631CONFIG_IP_NF_ARPFILTER=m
632CONFIG_IP_NF_ARP_MANGLE=m
633
634#
635# IPv6: Netfilter Configuration
636#
637CONFIG_NF_CONNTRACK_IPV6=y
638CONFIG_IP6_NF_QUEUE=m
639CONFIG_IP6_NF_IPTABLES=y
640CONFIG_IP6_NF_MATCH_RT=m
641CONFIG_IP6_NF_MATCH_OPTS=m
642CONFIG_IP6_NF_MATCH_FRAG=m
643CONFIG_IP6_NF_MATCH_HL=m
644CONFIG_IP6_NF_MATCH_IPV6HEADER=m
645CONFIG_IP6_NF_MATCH_AH=m
646CONFIG_IP6_NF_MATCH_MH=m
647CONFIG_IP6_NF_MATCH_EUI64=m
648CONFIG_IP6_NF_FILTER=y
649CONFIG_IP6_NF_TARGET_LOG=m
650CONFIG_IP6_NF_TARGET_REJECT=y
651CONFIG_IP6_NF_MANGLE=m
652CONFIG_IP6_NF_TARGET_HL=m
653CONFIG_IP6_NF_RAW=m
654# CONFIG_IP6_NF_SECURITY is not set
655# CONFIG_IP_DCCP is not set
656# CONFIG_IP_SCTP is not set
657# CONFIG_TIPC is not set
658# CONFIG_ATM is not set
659# CONFIG_BRIDGE is not set
660# CONFIG_VLAN_8021Q is not set
661# CONFIG_DECNET is not set
662# CONFIG_LLC2 is not set
663# CONFIG_IPX is not set
664# CONFIG_ATALK is not set
665# CONFIG_X25 is not set
666# CONFIG_LAPB is not set
667# CONFIG_ECONET is not set
668# CONFIG_WAN_ROUTER is not set
669# CONFIG_NET_SCHED is not set
670CONFIG_NET_CLS_ROUTE=y
671
672#
673# Network testing
674#
675# CONFIG_NET_PKTGEN is not set
676# CONFIG_HAMRADIO is not set
677# CONFIG_CAN is not set
678# CONFIG_IRDA is not set
679CONFIG_BT=m
680CONFIG_BT_L2CAP=m
681CONFIG_BT_SCO=m
682CONFIG_BT_RFCOMM=m
683CONFIG_BT_RFCOMM_TTY=y
684CONFIG_BT_BNEP=m
685# CONFIG_BT_BNEP_MC_FILTER is not set
686# CONFIG_BT_BNEP_PROTO_FILTER is not set
687# CONFIG_BT_HIDP is not set
688
689#
690# Bluetooth device drivers
691#
692CONFIG_BT_HCIUSB=m
693CONFIG_BT_HCIUSB_SCO=y
694# CONFIG_BT_HCIBTUSB is not set
695CONFIG_BT_HCIBTSDIO=m
696CONFIG_BT_HCIUART=m
697CONFIG_BT_HCIUART_H4=y
698CONFIG_BT_HCIUART_BCSP=y
699CONFIG_BT_HCIUART_LL=y
700CONFIG_BT_HCIBCM203X=m
701CONFIG_BT_HCIBPA10X=m
702CONFIG_BT_HCIBFUSB=m
703CONFIG_BT_HCIVHCI=m
704# CONFIG_AF_RXRPC is not set
705CONFIG_FIB_RULES=y
706
707#
708# Wireless
709#
710CONFIG_CFG80211=m
711CONFIG_NL80211=y
712CONFIG_WIRELESS_EXT=y
713# CONFIG_WIRELESS_EXT_SYSFS is not set
714CONFIG_MAC80211=m
715
716#
717# Rate control algorithm selection
718#
719CONFIG_MAC80211_RC_PID=y
720CONFIG_MAC80211_RC_DEFAULT_PID=y
721CONFIG_MAC80211_RC_DEFAULT="pid"
722CONFIG_MAC80211_MESH=y
723CONFIG_MAC80211_LEDS=y
724CONFIG_MAC80211_DEBUGFS=y
725# CONFIG_MAC80211_DEBUG_MENU is not set
726CONFIG_IEEE80211=m
727# CONFIG_IEEE80211_DEBUG is not set
728CONFIG_IEEE80211_CRYPT_WEP=m
729CONFIG_IEEE80211_CRYPT_CCMP=m
730CONFIG_IEEE80211_CRYPT_TKIP=m
731CONFIG_RFKILL=m
732CONFIG_RFKILL_INPUT=m
733CONFIG_RFKILL_LEDS=y
734# CONFIG_NET_9P is not set
735
736#
737# Device Drivers
738#
739
740#
741# Generic Driver Options
742#
743CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
744CONFIG_STANDALONE=y
745CONFIG_PREVENT_FIRMWARE_BUILD=y
746CONFIG_FW_LOADER=y
747CONFIG_FIRMWARE_IN_KERNEL=y
748CONFIG_EXTRA_FIRMWARE=""
749# CONFIG_DEBUG_DRIVER is not set
750CONFIG_DEBUG_DEVRES=y
751# CONFIG_SYS_HYPERVISOR is not set
752CONFIG_CONNECTOR=y
753CONFIG_PROC_EVENTS=y
754# CONFIG_MTD is not set
755# CONFIG_PARPORT is not set
756CONFIG_PNP=y
757# CONFIG_PNP_DEBUG is not set
758
759#
760# Protocols
761#
762CONFIG_PNPACPI=y
763CONFIG_BLK_DEV=y
764# CONFIG_BLK_DEV_FD is not set
765# CONFIG_BLK_CPQ_DA is not set
766# CONFIG_BLK_CPQ_CISS_DA is not set
767# CONFIG_BLK_DEV_DAC960 is not set
768# CONFIG_BLK_DEV_UMEM is not set
769# CONFIG_BLK_DEV_COW_COMMON is not set
770CONFIG_BLK_DEV_LOOP=y
771CONFIG_BLK_DEV_CRYPTOLOOP=m
772# CONFIG_BLK_DEV_NBD is not set
773# CONFIG_BLK_DEV_SX8 is not set
774# CONFIG_BLK_DEV_UB is not set
775CONFIG_BLK_DEV_RAM=y
776CONFIG_BLK_DEV_RAM_COUNT=16
777CONFIG_BLK_DEV_RAM_SIZE=262144
778# CONFIG_BLK_DEV_XIP is not set
779CONFIG_CDROM_PKTCDVD=m
780CONFIG_CDROM_PKTCDVD_BUFFERS=8
781# CONFIG_CDROM_PKTCDVD_WCACHE is not set
782# CONFIG_ATA_OVER_ETH is not set
783# CONFIG_BLK_DEV_HD is not set
784CONFIG_MISC_DEVICES=y
785# CONFIG_IBM_ASM is not set
786# CONFIG_PHANTOM is not set
787CONFIG_EEPROM_93CX6=m
788# CONFIG_SGI_IOC4 is not set
789CONFIG_TIFM_CORE=m
790CONFIG_TIFM_7XX1=m
791# CONFIG_ACER_WMI is not set
792# CONFIG_FUJITSU_LAPTOP is not set
793# CONFIG_TC1100_WMI is not set
794# CONFIG_HP_WMI is not set
795# CONFIG_MSI_LAPTOP is not set
796# CONFIG_COMPAL_LAPTOP is not set
797# CONFIG_SONY_LAPTOP is not set
798# CONFIG_THINKPAD_ACPI is not set
799# CONFIG_INTEL_MENLOW is not set
800CONFIG_EEEPC_LAPTOP=y
801# CONFIG_ENCLOSURE_SERVICES is not set
802# CONFIG_HP_ILO is not set
803CONFIG_HAVE_IDE=y
804# CONFIG_IDE is not set
805
806#
807# SCSI device support
808#
809CONFIG_RAID_ATTRS=m
810CONFIG_SCSI=y
811CONFIG_SCSI_DMA=y
812# CONFIG_SCSI_TGT is not set
813# CONFIG_SCSI_NETLINK is not set
814CONFIG_SCSI_PROC_FS=y
815
816#
817# SCSI support type (disk, tape, CD-ROM)
818#
819CONFIG_BLK_DEV_SD=y
820CONFIG_CHR_DEV_ST=m
821# CONFIG_CHR_DEV_OSST is not set
822CONFIG_BLK_DEV_SR=y
823CONFIG_BLK_DEV_SR_VENDOR=y
824# CONFIG_CHR_DEV_SG is not set
825CONFIG_CHR_DEV_SCH=m
826
827#
828# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
829#
830CONFIG_SCSI_MULTI_LUN=y
831CONFIG_SCSI_CONSTANTS=y
832CONFIG_SCSI_LOGGING=y
833CONFIG_SCSI_SCAN_ASYNC=y
834CONFIG_SCSI_WAIT_SCAN=m
835
836#
837# SCSI Transports
838#
839# CONFIG_SCSI_SPI_ATTRS is not set
840# CONFIG_SCSI_FC_ATTRS is not set
841# CONFIG_SCSI_ISCSI_ATTRS is not set
842# CONFIG_SCSI_SAS_ATTRS is not set
843# CONFIG_SCSI_SAS_LIBSAS is not set
844# CONFIG_SCSI_SRP_ATTRS is not set
845CONFIG_SCSI_LOWLEVEL=y
846# CONFIG_ISCSI_TCP is not set
847# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
848# CONFIG_SCSI_3W_9XXX is not set
849# CONFIG_SCSI_ACARD is not set
850# CONFIG_SCSI_AACRAID is not set
851# CONFIG_SCSI_AIC7XXX is not set
852# CONFIG_SCSI_AIC7XXX_OLD is not set
853# CONFIG_SCSI_AIC79XX is not set
854# CONFIG_SCSI_AIC94XX is not set
855# CONFIG_SCSI_DPT_I2O is not set
856# CONFIG_SCSI_ADVANSYS is not set
857# CONFIG_SCSI_ARCMSR is not set
858# CONFIG_MEGARAID_NEWGEN is not set
859# CONFIG_MEGARAID_LEGACY is not set
860# CONFIG_MEGARAID_SAS is not set
861# CONFIG_SCSI_HPTIOP is not set
862# CONFIG_SCSI_BUSLOGIC is not set
863# CONFIG_SCSI_DMX3191D is not set
864# CONFIG_SCSI_EATA is not set
865# CONFIG_SCSI_FUTURE_DOMAIN is not set
866# CONFIG_SCSI_GDTH is not set
867# CONFIG_SCSI_IPS is not set
868# CONFIG_SCSI_INITIO is not set
869# CONFIG_SCSI_INIA100 is not set
870# CONFIG_SCSI_MVSAS is not set
871# CONFIG_SCSI_STEX is not set
872# CONFIG_SCSI_SYM53C8XX_2 is not set
873# CONFIG_SCSI_IPR is not set
874# CONFIG_SCSI_QLOGIC_1280 is not set
875# CONFIG_SCSI_QLA_FC is not set
876# CONFIG_SCSI_QLA_ISCSI is not set
877# CONFIG_SCSI_LPFC is not set
878# CONFIG_SCSI_DC395x is not set
879# CONFIG_SCSI_DC390T is not set
880# CONFIG_SCSI_NSP32 is not set
881# CONFIG_SCSI_DEBUG is not set
882# CONFIG_SCSI_SRP is not set
883# CONFIG_SCSI_DH is not set
884CONFIG_ATA=y
885# CONFIG_ATA_NONSTANDARD is not set
886CONFIG_ATA_ACPI=y
887# CONFIG_SATA_PMP is not set
888CONFIG_SATA_AHCI=y
889# CONFIG_SATA_SIL24 is not set
890CONFIG_ATA_SFF=y
891# CONFIG_SATA_SVW is not set
892CONFIG_ATA_PIIX=y
893# CONFIG_SATA_MV is not set
894# CONFIG_SATA_NV is not set
895# CONFIG_PDC_ADMA is not set
896# CONFIG_SATA_QSTOR is not set
897# CONFIG_SATA_PROMISE is not set
898# CONFIG_SATA_SX4 is not set
899# CONFIG_SATA_SIL is not set
900# CONFIG_SATA_SIS is not set
901# CONFIG_SATA_ULI is not set
902# CONFIG_SATA_VIA is not set
903# CONFIG_SATA_VITESSE is not set
904# CONFIG_SATA_INIC162X is not set
905# CONFIG_PATA_ACPI is not set
906# CONFIG_PATA_ALI is not set
907# CONFIG_PATA_AMD is not set
908# CONFIG_PATA_ARTOP is not set
909# CONFIG_PATA_ATIIXP is not set
910# CONFIG_PATA_CMD640_PCI is not set
911# CONFIG_PATA_CMD64X is not set
912# CONFIG_PATA_CS5520 is not set
913# CONFIG_PATA_CS5530 is not set
914# CONFIG_PATA_CS5535 is not set
915# CONFIG_PATA_CS5536 is not set
916# CONFIG_PATA_CYPRESS is not set
917# CONFIG_PATA_EFAR is not set
918# CONFIG_ATA_GENERIC is not set
919# CONFIG_PATA_HPT366 is not set
920# CONFIG_PATA_HPT37X is not set
921# CONFIG_PATA_HPT3X2N is not set
922# CONFIG_PATA_HPT3X3 is not set
923# CONFIG_PATA_IT821X is not set
924# CONFIG_PATA_IT8213 is not set
925# CONFIG_PATA_JMICRON is not set
926# CONFIG_PATA_TRIFLEX is not set
927# CONFIG_PATA_MARVELL is not set
928# CONFIG_PATA_MPIIX is not set
929# CONFIG_PATA_OLDPIIX is not set
930# CONFIG_PATA_NETCELL is not set
931# CONFIG_PATA_NINJA32 is not set
932# CONFIG_PATA_NS87410 is not set
933# CONFIG_PATA_NS87415 is not set
934# CONFIG_PATA_OPTI is not set
935# CONFIG_PATA_OPTIDMA is not set
936# CONFIG_PATA_PDC_OLD is not set
937# CONFIG_PATA_RADISYS is not set
938# CONFIG_PATA_RZ1000 is not set
939# CONFIG_PATA_SC1200 is not set
940# CONFIG_PATA_SERVERWORKS is not set
941# CONFIG_PATA_PDC2027X is not set
942# CONFIG_PATA_SIL680 is not set
943# CONFIG_PATA_SIS is not set
944# CONFIG_PATA_VIA is not set
945# CONFIG_PATA_WINBOND is not set
946CONFIG_PATA_SCH=y
947# CONFIG_MD is not set
948# CONFIG_FUSION is not set
949
950#
951# IEEE 1394 (FireWire) support
952#
953
954#
955# Enable only one of the two stacks, unless you know what you are doing
956#
957# CONFIG_FIREWIRE is not set
958# CONFIG_IEEE1394 is not set
959# CONFIG_I2O is not set
960# CONFIG_MACINTOSH_DRIVERS is not set
961CONFIG_NETDEVICES=y
962# CONFIG_DUMMY is not set
963# CONFIG_BONDING is not set
964CONFIG_MACVLAN=m
965# CONFIG_EQUALIZER is not set
966# CONFIG_TUN is not set
967# CONFIG_VETH is not set
968# CONFIG_NET_SB1000 is not set
969# CONFIG_ARCNET is not set
970CONFIG_PHYLIB=m
971
972#
973# MII PHY device drivers
974#
975CONFIG_MARVELL_PHY=m
976CONFIG_DAVICOM_PHY=m
977CONFIG_QSEMI_PHY=m
978CONFIG_LXT_PHY=m
979CONFIG_CICADA_PHY=m
980CONFIG_VITESSE_PHY=m
981CONFIG_SMSC_PHY=m
982CONFIG_BROADCOM_PHY=m
983CONFIG_ICPLUS_PHY=m
984CONFIG_REALTEK_PHY=m
985CONFIG_MDIO_BITBANG=m
986CONFIG_NET_ETHERNET=y
987CONFIG_MII=y
988CONFIG_HAPPYMEAL=m
989CONFIG_SUNGEM=m
990CONFIG_CASSINI=m
991CONFIG_NET_VENDOR_3COM=y
992# CONFIG_VORTEX is not set
993# CONFIG_TYPHOON is not set
994# CONFIG_NET_TULIP is not set
995# CONFIG_HP100 is not set
996# CONFIG_IBM_NEW_EMAC_ZMII is not set
997# CONFIG_IBM_NEW_EMAC_RGMII is not set
998# CONFIG_IBM_NEW_EMAC_TAH is not set
999# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
1000# CONFIG_NET_PCI is not set
1001# CONFIG_B44 is not set
1002CONFIG_NETDEV_1000=y
1003# CONFIG_ACENIC is not set
1004# CONFIG_DL2K is not set
1005# CONFIG_E1000 is not set
1006# CONFIG_E1000E is not set
1007# CONFIG_IP1000 is not set
1008# CONFIG_IGB is not set
1009# CONFIG_NS83820 is not set
1010# CONFIG_HAMACHI is not set
1011# CONFIG_YELLOWFIN is not set
1012# CONFIG_R8169 is not set
1013# CONFIG_SIS190 is not set
1014# CONFIG_SKGE is not set
1015# CONFIG_SKY2 is not set
1016# CONFIG_VIA_VELOCITY is not set
1017# CONFIG_TIGON3 is not set
1018# CONFIG_BNX2 is not set
1019# CONFIG_QLA3XXX is not set
1020CONFIG_ATL1=y
1021CONFIG_ATL1E=y
1022# CONFIG_NETDEV_10000 is not set
1023# CONFIG_TR is not set
1024
1025#
1026# Wireless LAN
1027#
1028CONFIG_WLAN_PRE80211=y
1029# CONFIG_STRIP is not set
1030CONFIG_WLAN_80211=y
1031# CONFIG_IPW2100 is not set
1032# CONFIG_IPW2200 is not set
1033# CONFIG_LIBERTAS is not set
1034# CONFIG_AIRO is not set
1035# CONFIG_HERMES is not set
1036# CONFIG_ATMEL is not set
1037# CONFIG_PRISM54 is not set
1038CONFIG_USB_ZD1201=m
1039CONFIG_USB_NET_RNDIS_WLAN=m
1040CONFIG_RTL8180=m
1041CONFIG_RTL8187=m
1042# CONFIG_ADM8211 is not set
1043# CONFIG_MAC80211_HWSIM is not set
1044# CONFIG_P54_COMMON is not set
1045CONFIG_ATH5K=m
1046# CONFIG_ATH5K_DEBUG is not set
1047# CONFIG_ATH9K is not set
1048CONFIG_IWLWIFI=m
1049CONFIG_IWLCORE=m
1050# CONFIG_IWLWIFI_LEDS is not set
1051CONFIG_IWLWIFI_RFKILL=y
1052# CONFIG_IWLWIFI_DEBUG is not set
1053# CONFIG_IWLAGN is not set
1054CONFIG_IWL3945=m
1055CONFIG_IWL3945_RFKILL=y
1056# CONFIG_IWL3945_SPECTRUM_MEASUREMENT is not set
1057# CONFIG_IWL3945_LEDS is not set
1058# CONFIG_IWL3945_DEBUG is not set
1059# CONFIG_HOSTAP is not set
1060# CONFIG_B43 is not set
1061# CONFIG_B43LEGACY is not set
1062# CONFIG_ZD1211RW is not set
1063CONFIG_RT2X00=m
1064CONFIG_RT2X00_LIB=m
1065CONFIG_RT2X00_LIB_PCI=m
1066CONFIG_RT2X00_LIB_USB=m
1067CONFIG_RT2X00_LIB_FIRMWARE=y
1068CONFIG_RT2X00_LIB_RFKILL=y
1069CONFIG_RT2X00_LIB_LEDS=y
1070CONFIG_RT2400PCI=m
1071CONFIG_RT2400PCI_RFKILL=y
1072CONFIG_RT2400PCI_LEDS=y
1073CONFIG_RT2500PCI=m
1074CONFIG_RT2500PCI_RFKILL=y
1075CONFIG_RT2500PCI_LEDS=y
1076CONFIG_RT61PCI=m
1077CONFIG_RT61PCI_RFKILL=y
1078CONFIG_RT61PCI_LEDS=y
1079CONFIG_RT2500USB=m
1080CONFIG_RT2500USB_LEDS=y
1081CONFIG_RT73USB=m
1082CONFIG_RT73USB_LEDS=y
1083CONFIG_RT2X00_LIB_DEBUGFS=y
1084# CONFIG_RT2X00_DEBUG is not set
1085
1086#
1087# USB Network Adapters
1088#
1089CONFIG_USB_CATC=m
1090CONFIG_USB_KAWETH=m
1091CONFIG_USB_PEGASUS=m
1092CONFIG_USB_RTL8150=m
1093CONFIG_USB_USBNET=m
1094CONFIG_USB_NET_AX8817X=m
1095CONFIG_USB_NET_CDCETHER=m
1096CONFIG_USB_NET_DM9601=m
1097CONFIG_USB_NET_GL620A=m
1098CONFIG_USB_NET_NET1080=m
1099CONFIG_USB_NET_PLUSB=m
1100CONFIG_USB_NET_MCS7830=m
1101CONFIG_USB_NET_RNDIS_HOST=m
1102CONFIG_USB_NET_CDC_SUBSET=m
1103CONFIG_USB_ALI_M5632=y
1104CONFIG_USB_AN2720=y
1105CONFIG_USB_BELKIN=y
1106CONFIG_USB_ARMLINUX=y
1107CONFIG_USB_EPSON2888=y
1108CONFIG_USB_KC2190=y
1109CONFIG_USB_NET_ZAURUS=m
1110# CONFIG_USB_HSO is not set
1111# CONFIG_WAN is not set
1112# CONFIG_FDDI is not set
1113# CONFIG_HIPPI is not set
1114CONFIG_PPP=m
1115CONFIG_PPP_MULTILINK=y
1116CONFIG_PPP_FILTER=y
1117CONFIG_PPP_ASYNC=m
1118CONFIG_PPP_SYNC_TTY=m
1119CONFIG_PPP_DEFLATE=m
1120# CONFIG_PPP_BSDCOMP is not set
1121CONFIG_PPP_MPPE=m
1122CONFIG_PPPOE=m
1123CONFIG_PPPOL2TP=m
1124# CONFIG_SLIP is not set
1125CONFIG_SLHC=m
1126CONFIG_NET_FC=y
1127CONFIG_NETCONSOLE=m
1128CONFIG_NETCONSOLE_DYNAMIC=y
1129CONFIG_NETPOLL=y
1130CONFIG_NETPOLL_TRAP=y
1131CONFIG_NET_POLL_CONTROLLER=y
1132# CONFIG_ISDN is not set
1133# CONFIG_PHONE is not set
1134
1135#
1136# Input device support
1137#
1138CONFIG_INPUT=y
1139CONFIG_INPUT_FF_MEMLESS=y
1140CONFIG_INPUT_POLLDEV=m
1141
1142#
1143# Userland interfaces
1144#
1145CONFIG_INPUT_MOUSEDEV=y
1146# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
1147CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
1148CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
1149CONFIG_INPUT_JOYDEV=m
1150CONFIG_INPUT_EVDEV=y
1151# CONFIG_INPUT_EVBUG is not set
1152
1153#
1154# Input Device Drivers
1155#
1156CONFIG_INPUT_KEYBOARD=y
1157CONFIG_KEYBOARD_ATKBD=y
1158# CONFIG_KEYBOARD_SUNKBD is not set
1159# CONFIG_KEYBOARD_LKKBD is not set
1160# CONFIG_KEYBOARD_XTKBD is not set
1161# CONFIG_KEYBOARD_NEWTON is not set
1162# CONFIG_KEYBOARD_STOWAWAY is not set
1163CONFIG_INPUT_MOUSE=y
1164CONFIG_MOUSE_PS2=y
1165CONFIG_MOUSE_PS2_ALPS=y
1166CONFIG_MOUSE_PS2_LOGIPS2PP=y
1167CONFIG_MOUSE_PS2_SYNAPTICS=y
1168CONFIG_MOUSE_PS2_LIFEBOOK=y
1169CONFIG_MOUSE_PS2_TRACKPOINT=y
1170# CONFIG_MOUSE_PS2_TOUCHKIT is not set
1171CONFIG_MOUSE_SERIAL=m
1172# CONFIG_MOUSE_APPLETOUCH is not set
1173# CONFIG_MOUSE_BCM5974 is not set
1174CONFIG_MOUSE_VSXXXAA=m
1175CONFIG_INPUT_JOYSTICK=y
1176# CONFIG_JOYSTICK_ANALOG is not set
1177# CONFIG_JOYSTICK_A3D is not set
1178# CONFIG_JOYSTICK_ADI is not set
1179# CONFIG_JOYSTICK_COBRA is not set
1180# CONFIG_JOYSTICK_GF2K is not set
1181# CONFIG_JOYSTICK_GRIP is not set
1182# CONFIG_JOYSTICK_GRIP_MP is not set
1183# CONFIG_JOYSTICK_GUILLEMOT is not set
1184# CONFIG_JOYSTICK_INTERACT is not set
1185# CONFIG_JOYSTICK_SIDEWINDER is not set
1186# CONFIG_JOYSTICK_TMDC is not set
1187# CONFIG_JOYSTICK_IFORCE is not set
1188# CONFIG_JOYSTICK_WARRIOR is not set
1189# CONFIG_JOYSTICK_MAGELLAN is not set
1190# CONFIG_JOYSTICK_SPACEORB is not set
1191# CONFIG_JOYSTICK_SPACEBALL is not set
1192# CONFIG_JOYSTICK_STINGER is not set
1193# CONFIG_JOYSTICK_TWIDJOY is not set
1194# CONFIG_JOYSTICK_ZHENHUA is not set
1195# CONFIG_JOYSTICK_JOYDUMP is not set
1196# CONFIG_JOYSTICK_XPAD is not set
1197# CONFIG_INPUT_TABLET is not set
1198CONFIG_INPUT_TOUCHSCREEN=y
1199CONFIG_TOUCHSCREEN_FUJITSU=m
1200CONFIG_TOUCHSCREEN_GUNZE=m
1201CONFIG_TOUCHSCREEN_ELO=m
1202CONFIG_TOUCHSCREEN_MTOUCH=m
1203CONFIG_TOUCHSCREEN_INEXIO=m
1204CONFIG_TOUCHSCREEN_MK712=m
1205CONFIG_TOUCHSCREEN_PENMOUNT=m
1206CONFIG_TOUCHSCREEN_TOUCHRIGHT=m
1207CONFIG_TOUCHSCREEN_TOUCHWIN=m
1208CONFIG_TOUCHSCREEN_UCB1400=m
1209# CONFIG_TOUCHSCREEN_WM97XX is not set
1210CONFIG_TOUCHSCREEN_USB_COMPOSITE=m
1211CONFIG_TOUCHSCREEN_USB_EGALAX=y
1212CONFIG_TOUCHSCREEN_USB_PANJIT=y
1213CONFIG_TOUCHSCREEN_USB_3M=y
1214CONFIG_TOUCHSCREEN_USB_ITM=y
1215CONFIG_TOUCHSCREEN_USB_ETURBO=y
1216CONFIG_TOUCHSCREEN_USB_GUNZE=y
1217CONFIG_TOUCHSCREEN_USB_DMC_TSC10=y
1218CONFIG_TOUCHSCREEN_USB_IRTOUCH=y
1219CONFIG_TOUCHSCREEN_USB_IDEALTEK=y
1220CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH=y
1221CONFIG_TOUCHSCREEN_USB_GOTOP=y
1222CONFIG_TOUCHSCREEN_TOUCHIT213=m
1223CONFIG_INPUT_MISC=y
1224# CONFIG_INPUT_PCSPKR is not set
1225# CONFIG_INPUT_APANEL is not set
1226# CONFIG_INPUT_WISTRON_BTNS is not set
1227CONFIG_INPUT_ATLAS_BTNS=m
1228CONFIG_INPUT_ATI_REMOTE=m
1229CONFIG_INPUT_ATI_REMOTE2=m
1230CONFIG_INPUT_KEYSPAN_REMOTE=m
1231CONFIG_INPUT_POWERMATE=m
1232CONFIG_INPUT_YEALINK=m
1233CONFIG_INPUT_UINPUT=m
1234
1235#
1236# Hardware I/O ports
1237#
1238CONFIG_SERIO=y
1239CONFIG_SERIO_I8042=y
1240CONFIG_SERIO_SERPORT=y
1241# CONFIG_SERIO_CT82C710 is not set
1242# CONFIG_SERIO_PCIPS2 is not set
1243CONFIG_SERIO_LIBPS2=y
1244CONFIG_SERIO_RAW=m
1245# CONFIG_GAMEPORT is not set
1246
1247#
1248# Character devices
1249#
1250CONFIG_VT=y
1251CONFIG_CONSOLE_TRANSLATIONS=y
1252CONFIG_VT_CONSOLE=y
1253CONFIG_HW_CONSOLE=y
1254CONFIG_VT_HW_CONSOLE_BINDING=y
1255# CONFIG_DEVKMEM is not set
1256# CONFIG_SERIAL_NONSTANDARD is not set
1257# CONFIG_NOZOMI is not set
1258
1259#
1260# Serial drivers
1261#
1262# CONFIG_SERIAL_8250 is not set
1263CONFIG_FIX_EARLYCON_MEM=y
1264
1265#
1266# Non-8250 serial port support
1267#
1268# CONFIG_SERIAL_JSM is not set
1269CONFIG_UNIX98_PTYS=y
1270# CONFIG_LEGACY_PTYS is not set
1271# CONFIG_IPMI_HANDLER is not set
1272# CONFIG_HW_RANDOM is not set
1273# CONFIG_NVRAM is not set
1274# CONFIG_R3964 is not set
1275# CONFIG_APPLICOM is not set
1276# CONFIG_SONYPI is not set
1277# CONFIG_MWAVE is not set
1278# CONFIG_PC8736x_GPIO is not set
1279# CONFIG_NSC_GPIO is not set
1280# CONFIG_CS5535_GPIO is not set
1281# CONFIG_RAW_DRIVER is not set
1282CONFIG_HPET=y
1283# CONFIG_HPET_MMAP is not set
1284# CONFIG_HANGCHECK_TIMER is not set
1285# CONFIG_TCG_TPM is not set
1286# CONFIG_TELCLOCK is not set
1287CONFIG_DEVPORT=y
1288CONFIG_I2C=y
1289CONFIG_I2C_BOARDINFO=y
1290# CONFIG_I2C_CHARDEV is not set
1291CONFIG_I2C_HELPER_AUTO=y
1292CONFIG_I2C_ALGOBIT=y
1293
1294#
1295# I2C Hardware Bus support
1296#
1297
1298#
1299# PC SMBus host controller drivers
1300#
1301# CONFIG_I2C_ALI1535 is not set
1302# CONFIG_I2C_ALI1563 is not set
1303# CONFIG_I2C_ALI15X3 is not set
1304# CONFIG_I2C_AMD756 is not set
1305# CONFIG_I2C_AMD8111 is not set
1306# CONFIG_I2C_I801 is not set
1307# CONFIG_I2C_ISCH is not set
1308# CONFIG_I2C_PIIX4 is not set
1309# CONFIG_I2C_NFORCE2 is not set
1310# CONFIG_I2C_SIS5595 is not set
1311# CONFIG_I2C_SIS630 is not set
1312# CONFIG_I2C_SIS96X is not set
1313# CONFIG_I2C_VIA is not set
1314# CONFIG_I2C_VIAPRO is not set
1315
1316#
1317# I2C system bus drivers (mostly embedded / system-on-chip)
1318#
1319# CONFIG_I2C_OCORES is not set
1320# CONFIG_I2C_SIMTEC is not set
1321
1322#
1323# External I2C/SMBus adapter drivers
1324#
1325# CONFIG_I2C_PARPORT_LIGHT is not set
1326# CONFIG_I2C_TAOS_EVM is not set
1327# CONFIG_I2C_TINY_USB is not set
1328
1329#
1330# Graphics adapter I2C/DDC channel drivers
1331#
1332# CONFIG_I2C_VOODOO3 is not set
1333
1334#
1335# Other I2C/SMBus bus drivers
1336#
1337# CONFIG_I2C_PCA_PLATFORM is not set
1338# CONFIG_I2C_STUB is not set
1339# CONFIG_SCx200_ACB is not set
1340
1341#
1342# Miscellaneous I2C Chip support
1343#
1344# CONFIG_DS1682 is not set
1345# CONFIG_AT24 is not set
1346# CONFIG_SENSORS_EEPROM is not set
1347# CONFIG_SENSORS_PCF8574 is not set
1348# CONFIG_PCF8575 is not set
1349# CONFIG_SENSORS_PCA9539 is not set
1350# CONFIG_SENSORS_PCF8591 is not set
1351# CONFIG_SENSORS_MAX6875 is not set
1352# CONFIG_SENSORS_TSL2550 is not set
1353# CONFIG_I2C_DEBUG_CORE is not set
1354# CONFIG_I2C_DEBUG_ALGO is not set
1355# CONFIG_I2C_DEBUG_BUS is not set
1356# CONFIG_I2C_DEBUG_CHIP is not set
1357# CONFIG_SPI is not set
1358CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
1359# CONFIG_GPIOLIB is not set
1360# CONFIG_W1 is not set
1361CONFIG_POWER_SUPPLY=y
1362# CONFIG_POWER_SUPPLY_DEBUG is not set
1363# CONFIG_PDA_POWER is not set
1364# CONFIG_BATTERY_DS2760 is not set
1365CONFIG_HWMON=y
1366# CONFIG_HWMON_VID is not set
1367# CONFIG_SENSORS_ABITUGURU is not set
1368# CONFIG_SENSORS_ABITUGURU3 is not set
1369# CONFIG_SENSORS_AD7414 is not set
1370# CONFIG_SENSORS_AD7418 is not set
1371# CONFIG_SENSORS_ADM1021 is not set
1372# CONFIG_SENSORS_ADM1025 is not set
1373# CONFIG_SENSORS_ADM1026 is not set
1374# CONFIG_SENSORS_ADM1029 is not set
1375# CONFIG_SENSORS_ADM1031 is not set
1376# CONFIG_SENSORS_ADM9240 is not set
1377# CONFIG_SENSORS_ADT7470 is not set
1378# CONFIG_SENSORS_ADT7473 is not set
1379# CONFIG_SENSORS_K8TEMP is not set
1380# CONFIG_SENSORS_ASB100 is not set
1381# CONFIG_SENSORS_ATXP1 is not set
1382# CONFIG_SENSORS_DS1621 is not set
1383# CONFIG_SENSORS_I5K_AMB is not set
1384# CONFIG_SENSORS_F71805F is not set
1385# CONFIG_SENSORS_F71882FG is not set
1386# CONFIG_SENSORS_F75375S is not set
1387# CONFIG_SENSORS_FSCHER is not set
1388# CONFIG_SENSORS_FSCPOS is not set
1389# CONFIG_SENSORS_FSCHMD is not set
1390# CONFIG_SENSORS_GL518SM is not set
1391# CONFIG_SENSORS_GL520SM is not set
1392# CONFIG_SENSORS_CORETEMP is not set
1393# CONFIG_SENSORS_IT87 is not set
1394# CONFIG_SENSORS_LM63 is not set
1395# CONFIG_SENSORS_LM75 is not set
1396# CONFIG_SENSORS_LM77 is not set
1397# CONFIG_SENSORS_LM78 is not set
1398# CONFIG_SENSORS_LM80 is not set
1399# CONFIG_SENSORS_LM83 is not set
1400# CONFIG_SENSORS_LM85 is not set
1401# CONFIG_SENSORS_LM87 is not set
1402# CONFIG_SENSORS_LM90 is not set
1403# CONFIG_SENSORS_LM92 is not set
1404# CONFIG_SENSORS_LM93 is not set
1405# CONFIG_SENSORS_MAX1619 is not set
1406# CONFIG_SENSORS_MAX6650 is not set
1407# CONFIG_SENSORS_PC87360 is not set
1408# CONFIG_SENSORS_PC87427 is not set
1409# CONFIG_SENSORS_SIS5595 is not set
1410# CONFIG_SENSORS_DME1737 is not set
1411# CONFIG_SENSORS_SMSC47M1 is not set
1412# CONFIG_SENSORS_SMSC47M192 is not set
1413# CONFIG_SENSORS_SMSC47B397 is not set
1414# CONFIG_SENSORS_ADS7828 is not set
1415# CONFIG_SENSORS_THMC50 is not set
1416# CONFIG_SENSORS_VIA686A is not set
1417# CONFIG_SENSORS_VT1211 is not set
1418# CONFIG_SENSORS_VT8231 is not set
1419# CONFIG_SENSORS_W83781D is not set
1420# CONFIG_SENSORS_W83791D is not set
1421# CONFIG_SENSORS_W83792D is not set
1422# CONFIG_SENSORS_W83793 is not set
1423# CONFIG_SENSORS_W83L785TS is not set
1424# CONFIG_SENSORS_W83L786NG is not set
1425# CONFIG_SENSORS_W83627HF is not set
1426# CONFIG_SENSORS_W83627EHF is not set
1427# CONFIG_SENSORS_HDAPS is not set
1428# CONFIG_SENSORS_APPLESMC is not set
1429# CONFIG_HWMON_DEBUG_CHIP is not set
1430CONFIG_THERMAL=y
1431# CONFIG_THERMAL_HWMON is not set
1432# CONFIG_WATCHDOG is not set
1433
1434#
1435# Sonics Silicon Backplane
1436#
1437CONFIG_SSB_POSSIBLE=y
1438# CONFIG_SSB is not set
1439
1440#
1441# Multifunction device drivers
1442#
1443# CONFIG_MFD_CORE is not set
1444# CONFIG_MFD_SM501 is not set
1445# CONFIG_HTC_PASIC3 is not set
1446# CONFIG_MFD_TMIO is not set
1447
1448#
1449# Multimedia devices
1450#
1451
1452#
1453# Multimedia core support
1454#
1455CONFIG_VIDEO_DEV=y
1456CONFIG_VIDEO_V4L2_COMMON=y
1457# CONFIG_VIDEO_ALLOW_V4L1 is not set
1458CONFIG_VIDEO_V4L1_COMPAT=y
1459CONFIG_DVB_CORE=y
1460CONFIG_VIDEO_MEDIA=y
1461
1462#
1463# Multimedia drivers
1464#
1465# CONFIG_MEDIA_ATTACH is not set
1466CONFIG_MEDIA_TUNER=y
1467# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set
1468CONFIG_MEDIA_TUNER_SIMPLE=y
1469CONFIG_MEDIA_TUNER_TDA8290=y
1470CONFIG_MEDIA_TUNER_TDA9887=y
1471CONFIG_MEDIA_TUNER_TEA5761=y
1472CONFIG_MEDIA_TUNER_TEA5767=y
1473CONFIG_MEDIA_TUNER_MT20XX=y
1474CONFIG_MEDIA_TUNER_XC2028=y
1475CONFIG_MEDIA_TUNER_XC5000=y
1476CONFIG_VIDEO_V4L2=y
1477CONFIG_VIDEO_CAPTURE_DRIVERS=y
1478# CONFIG_VIDEO_ADV_DEBUG is not set
1479CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
1480# CONFIG_VIDEO_VIVI is not set
1481# CONFIG_VIDEO_BT848 is not set
1482# CONFIG_VIDEO_SAA5246A is not set
1483# CONFIG_VIDEO_SAA5249 is not set
1484# CONFIG_VIDEO_SAA7134 is not set
1485# CONFIG_VIDEO_HEXIUM_ORION is not set
1486# CONFIG_VIDEO_HEXIUM_GEMINI is not set
1487# CONFIG_VIDEO_CX88 is not set
1488# CONFIG_VIDEO_CX23885 is not set
1489# CONFIG_VIDEO_AU0828 is not set
1490# CONFIG_VIDEO_CX18 is not set
1491# CONFIG_VIDEO_CAFE_CCIC is not set
1492CONFIG_V4L_USB_DRIVERS=y
1493CONFIG_USB_VIDEO_CLASS=y
1494CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y
1495# CONFIG_USB_GSPCA is not set
1496# CONFIG_VIDEO_PVRUSB2 is not set
1497# CONFIG_VIDEO_EM28XX is not set
1498# CONFIG_VIDEO_USBVISION is not set
1499# CONFIG_USB_ET61X251 is not set
1500# CONFIG_USB_SN9C102 is not set
1501# CONFIG_USB_ZC0301 is not set
1502# CONFIG_USB_ZR364XX is not set
1503# CONFIG_USB_STKWEBCAM is not set
1504# CONFIG_USB_S2255 is not set
1505# CONFIG_SOC_CAMERA is not set
1506# CONFIG_VIDEO_SH_MOBILE_CEU is not set
1507# CONFIG_RADIO_ADAPTERS is not set
1508# CONFIG_DVB_CAPTURE_DRIVERS is not set
1509# CONFIG_DAB is not set
1510
1511#
1512# Graphics support
1513#
1514CONFIG_AGP=y
1515# CONFIG_AGP_ALI is not set
1516# CONFIG_AGP_ATI is not set
1517# CONFIG_AGP_AMD is not set
1518CONFIG_AGP_AMD64=y
1519CONFIG_AGP_INTEL=y
1520# CONFIG_AGP_NVIDIA is not set
1521# CONFIG_AGP_SIS is not set
1522# CONFIG_AGP_SWORKS is not set
1523# CONFIG_AGP_VIA is not set
1524# CONFIG_AGP_EFFICEON is not set
1525CONFIG_DRM=y
1526# CONFIG_DRM_TDFX is not set
1527# CONFIG_DRM_R128 is not set
1528# CONFIG_DRM_RADEON is not set
1529CONFIG_DRM_I810=y
1530# CONFIG_DRM_I830 is not set
1531CONFIG_DRM_I915=y
1532# CONFIG_DRM_MGA is not set
1533# CONFIG_DRM_SIS is not set
1534# CONFIG_DRM_VIA is not set
1535# CONFIG_DRM_SAVAGE is not set
1536# CONFIG_VGASTATE is not set
1537CONFIG_VIDEO_OUTPUT_CONTROL=y
1538CONFIG_FB=y
1539CONFIG_FIRMWARE_EDID=y
1540CONFIG_FB_DDC=y
1541CONFIG_FB_CFB_FILLRECT=y
1542CONFIG_FB_CFB_COPYAREA=y
1543CONFIG_FB_CFB_IMAGEBLIT=y
1544# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
1545# CONFIG_FB_SYS_FILLRECT is not set
1546# CONFIG_FB_SYS_COPYAREA is not set
1547# CONFIG_FB_SYS_IMAGEBLIT is not set
1548# CONFIG_FB_FOREIGN_ENDIAN is not set
1549# CONFIG_FB_SYS_FOPS is not set
1550# CONFIG_FB_SVGALIB is not set
1551# CONFIG_FB_MACMODES is not set
1552# CONFIG_FB_BACKLIGHT is not set
1553CONFIG_FB_MODE_HELPERS=y
1554# CONFIG_FB_TILEBLITTING is not set
1555
1556#
1557# Frame buffer hardware drivers
1558#
1559# CONFIG_FB_CIRRUS is not set
1560# CONFIG_FB_PM2 is not set
1561# CONFIG_FB_CYBER2000 is not set
1562# CONFIG_FB_ARC is not set
1563# CONFIG_FB_ASILIANT is not set
1564# CONFIG_FB_IMSTT is not set
1565# CONFIG_FB_VGA16 is not set
1566# CONFIG_FB_UVESA is not set
1567# CONFIG_FB_VESA is not set
1568# CONFIG_FB_EFI is not set
1569# CONFIG_FB_N411 is not set
1570# CONFIG_FB_HGA is not set
1571# CONFIG_FB_S1D13XXX is not set
1572# CONFIG_FB_NVIDIA is not set
1573# CONFIG_FB_RIVA is not set
1574# CONFIG_FB_I810 is not set
1575# CONFIG_FB_LE80578 is not set
1576CONFIG_FB_INTEL=y
1577CONFIG_FB_INTEL_DEBUG=y
1578CONFIG_FB_INTEL_I2C=y
1579# CONFIG_FB_MATROX is not set
1580# CONFIG_FB_RADEON is not set
1581# CONFIG_FB_ATY128 is not set
1582# CONFIG_FB_ATY is not set
1583# CONFIG_FB_S3 is not set
1584# CONFIG_FB_SAVAGE is not set
1585# CONFIG_FB_SIS is not set
1586# CONFIG_FB_NEOMAGIC is not set
1587# CONFIG_FB_KYRO is not set
1588# CONFIG_FB_3DFX is not set
1589# CONFIG_FB_VOODOO1 is not set
1590# CONFIG_FB_VT8623 is not set
1591# CONFIG_FB_CYBLA is not set
1592# CONFIG_FB_TRIDENT is not set
1593# CONFIG_FB_ARK is not set
1594# CONFIG_FB_PM3 is not set
1595# CONFIG_FB_CARMINE is not set
1596# CONFIG_FB_GEODE is not set
1597# CONFIG_FB_VIRTUAL is not set
1598CONFIG_BACKLIGHT_LCD_SUPPORT=y
1599CONFIG_LCD_CLASS_DEVICE=y
1600# CONFIG_LCD_ILI9320 is not set
1601CONFIG_LCD_PLATFORM=y
1602CONFIG_BACKLIGHT_CLASS_DEVICE=y
1603# CONFIG_BACKLIGHT_CORGI is not set
1604# CONFIG_BACKLIGHT_PROGEAR is not set
1605CONFIG_BACKLIGHT_MBP_NVIDIA=y
1606
1607#
1608# Display device support
1609#
1610CONFIG_DISPLAY_SUPPORT=y
1611
1612#
1613# Display hardware drivers
1614#
1615
1616#
1617# Console display driver support
1618#
1619CONFIG_VGA_CONSOLE=y
1620CONFIG_VGACON_SOFT_SCROLLBACK=y
1621CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=64
1622CONFIG_VIDEO_SELECT=y
1623CONFIG_DUMMY_CONSOLE=y
1624CONFIG_FRAMEBUFFER_CONSOLE=y
1625# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
1626# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
1627# CONFIG_FONTS is not set
1628CONFIG_FONT_8x8=y
1629CONFIG_FONT_8x16=y
1630# CONFIG_LOGO is not set
1631CONFIG_SOUND=y
1632CONFIG_SND=y
1633CONFIG_SND_TIMER=y
1634CONFIG_SND_PCM=y
1635CONFIG_SND_HWDEP=y
1636CONFIG_SND_RAWMIDI=m
1637CONFIG_SND_SEQUENCER=y
1638CONFIG_SND_SEQ_DUMMY=y
1639# CONFIG_SND_MIXER_OSS is not set
1640# CONFIG_SND_PCM_OSS is not set
1641# CONFIG_SND_SEQUENCER_OSS is not set
1642CONFIG_SND_DYNAMIC_MINORS=y
1643# CONFIG_SND_SUPPORT_OLD_API is not set
1644CONFIG_SND_VERBOSE_PROCFS=y
1645CONFIG_SND_VERBOSE_PRINTK=y
1646CONFIG_SND_DEBUG=y
1647# CONFIG_SND_DEBUG_VERBOSE is not set
1648CONFIG_SND_PCM_XRUN_DEBUG=y
1649CONFIG_SND_VMASTER=y
1650CONFIG_SND_AC97_CODEC=y
1651CONFIG_SND_DRIVERS=y
1652# CONFIG_SND_PCSP is not set
1653# CONFIG_SND_DUMMY is not set
1654# CONFIG_SND_VIRMIDI is not set
1655# CONFIG_SND_MTPAV is not set
1656# CONFIG_SND_SERIAL_U16550 is not set
1657# CONFIG_SND_MPU401 is not set
1658CONFIG_SND_AC97_POWER_SAVE=y
1659CONFIG_SND_AC97_POWER_SAVE_DEFAULT=5
1660CONFIG_SND_PCI=y
1661# CONFIG_SND_AD1889 is not set
1662# CONFIG_SND_ALS300 is not set
1663# CONFIG_SND_ALS4000 is not set
1664# CONFIG_SND_ALI5451 is not set
1665# CONFIG_SND_ATIIXP is not set
1666# CONFIG_SND_ATIIXP_MODEM is not set
1667# CONFIG_SND_AU8810 is not set
1668# CONFIG_SND_AU8820 is not set
1669# CONFIG_SND_AU8830 is not set
1670# CONFIG_SND_AW2 is not set
1671# CONFIG_SND_AZT3328 is not set
1672# CONFIG_SND_BT87X is not set
1673# CONFIG_SND_CA0106 is not set
1674# CONFIG_SND_CMIPCI is not set
1675# CONFIG_SND_OXYGEN is not set
1676# CONFIG_SND_CS4281 is not set
1677# CONFIG_SND_CS46XX is not set
1678# CONFIG_SND_CS5530 is not set
1679# CONFIG_SND_CS5535AUDIO is not set
1680# CONFIG_SND_DARLA20 is not set
1681# CONFIG_SND_GINA20 is not set
1682# CONFIG_SND_LAYLA20 is not set
1683# CONFIG_SND_DARLA24 is not set
1684# CONFIG_SND_GINA24 is not set
1685# CONFIG_SND_LAYLA24 is not set
1686# CONFIG_SND_MONA is not set
1687# CONFIG_SND_MIA is not set
1688# CONFIG_SND_ECHO3G is not set
1689# CONFIG_SND_INDIGO is not set
1690# CONFIG_SND_INDIGOIO is not set
1691# CONFIG_SND_INDIGODJ is not set
1692# CONFIG_SND_EMU10K1 is not set
1693# CONFIG_SND_EMU10K1X is not set
1694# CONFIG_SND_ENS1370 is not set
1695# CONFIG_SND_ENS1371 is not set
1696# CONFIG_SND_ES1938 is not set
1697# CONFIG_SND_ES1968 is not set
1698# CONFIG_SND_FM801 is not set
1699CONFIG_SND_HDA_INTEL=y
1700CONFIG_SND_HDA_HWDEP=y
1701CONFIG_SND_HDA_CODEC_REALTEK=y
1702CONFIG_SND_HDA_CODEC_ANALOG=y
1703CONFIG_SND_HDA_CODEC_SIGMATEL=y
1704CONFIG_SND_HDA_CODEC_VIA=y
1705CONFIG_SND_HDA_CODEC_ATIHDMI=y
1706CONFIG_SND_HDA_CODEC_CONEXANT=y
1707CONFIG_SND_HDA_CODEC_CMEDIA=y
1708CONFIG_SND_HDA_CODEC_SI3054=y
1709CONFIG_SND_HDA_GENERIC=y
1710CONFIG_SND_HDA_POWER_SAVE=y
1711CONFIG_SND_HDA_POWER_SAVE_DEFAULT=0
1712# CONFIG_SND_HDSP is not set
1713# CONFIG_SND_HDSPM is not set
1714# CONFIG_SND_HIFIER is not set
1715# CONFIG_SND_ICE1712 is not set
1716# CONFIG_SND_ICE1724 is not set
1717CONFIG_SND_INTEL8X0=y
1718# CONFIG_SND_INTEL8X0M is not set
1719# CONFIG_SND_KORG1212 is not set
1720# CONFIG_SND_MAESTRO3 is not set
1721# CONFIG_SND_MIXART is not set
1722# CONFIG_SND_NM256 is not set
1723# CONFIG_SND_PCXHR is not set
1724# CONFIG_SND_RIPTIDE is not set
1725# CONFIG_SND_RME32 is not set
1726# CONFIG_SND_RME96 is not set
1727# CONFIG_SND_RME9652 is not set
1728# CONFIG_SND_SIS7019 is not set
1729# CONFIG_SND_SONICVIBES is not set
1730# CONFIG_SND_TRIDENT is not set
1731# CONFIG_SND_VIA82XX is not set
1732# CONFIG_SND_VIA82XX_MODEM is not set
1733# CONFIG_SND_VIRTUOSO is not set
1734# CONFIG_SND_VX222 is not set
1735# CONFIG_SND_YMFPCI is not set
1736CONFIG_SND_USB=y
1737CONFIG_SND_USB_AUDIO=m
1738CONFIG_SND_USB_USX2Y=m
1739CONFIG_SND_USB_CAIAQ=m
1740CONFIG_SND_USB_CAIAQ_INPUT=y
1741# CONFIG_SND_SOC is not set
1742# CONFIG_SOUND_PRIME is not set
1743CONFIG_AC97_BUS=y
1744CONFIG_HID_SUPPORT=y
1745CONFIG_HID=y
1746CONFIG_HID_DEBUG=y
1747CONFIG_HIDRAW=y
1748
1749#
1750# USB Input Devices
1751#
1752CONFIG_USB_HID=y
1753CONFIG_USB_HIDINPUT_POWERBOOK=y
1754CONFIG_HID_FF=y
1755CONFIG_HID_PID=y
1756CONFIG_LOGITECH_FF=y
1757# CONFIG_LOGIRUMBLEPAD2_FF is not set
1758CONFIG_PANTHERLORD_FF=y
1759CONFIG_THRUSTMASTER_FF=y
1760CONFIG_ZEROPLUS_FF=y
1761CONFIG_USB_HIDDEV=y
1762CONFIG_USB_SUPPORT=y
1763CONFIG_USB_ARCH_HAS_HCD=y
1764CONFIG_USB_ARCH_HAS_OHCI=y
1765CONFIG_USB_ARCH_HAS_EHCI=y
1766CONFIG_USB=y
1767# CONFIG_USB_DEBUG is not set
1768CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
1769
1770#
1771# Miscellaneous USB options
1772#
1773CONFIG_USB_DEVICEFS=y
1774# CONFIG_USB_DEVICE_CLASS is not set
1775# CONFIG_USB_DYNAMIC_MINORS is not set
1776CONFIG_USB_SUSPEND=y
1777# CONFIG_USB_OTG is not set
1778CONFIG_USB_MON=y
1779
1780#
1781# USB Host Controller Drivers
1782#
1783# CONFIG_USB_C67X00_HCD is not set
1784CONFIG_USB_EHCI_HCD=y
1785CONFIG_USB_EHCI_ROOT_HUB_TT=y
1786CONFIG_USB_EHCI_TT_NEWSCHED=y
1787CONFIG_USB_ISP116X_HCD=m
1788# CONFIG_USB_ISP1760_HCD is not set
1789CONFIG_USB_OHCI_HCD=y
1790# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
1791# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
1792CONFIG_USB_OHCI_LITTLE_ENDIAN=y
1793CONFIG_USB_UHCI_HCD=y
1794CONFIG_USB_U132_HCD=m
1795CONFIG_USB_SL811_HCD=m
1796# CONFIG_USB_R8A66597_HCD is not set
1797
1798#
1799# USB Device Class drivers
1800#
1801CONFIG_USB_ACM=m
1802CONFIG_USB_PRINTER=m
1803# CONFIG_USB_WDM is not set
1804
1805#
1806# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
1807#
1808
1809#
1810# may also be needed; see USB_STORAGE Help for more information
1811#
1812CONFIG_USB_STORAGE=y
1813# CONFIG_USB_STORAGE_DEBUG is not set
1814CONFIG_USB_STORAGE_DATAFAB=y
1815CONFIG_USB_STORAGE_FREECOM=y
1816CONFIG_USB_STORAGE_ISD200=y
1817CONFIG_USB_STORAGE_DPCM=y
1818CONFIG_USB_STORAGE_USBAT=y
1819CONFIG_USB_STORAGE_SDDR09=y
1820CONFIG_USB_STORAGE_SDDR55=y
1821CONFIG_USB_STORAGE_JUMPSHOT=y
1822CONFIG_USB_STORAGE_ALAUDA=y
1823# CONFIG_USB_STORAGE_ONETOUCH is not set
1824CONFIG_USB_STORAGE_KARMA=y
1825# CONFIG_USB_STORAGE_SIERRA is not set
1826# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
1827# CONFIG_USB_LIBUSUAL is not set
1828
1829#
1830# USB Imaging devices
1831#
1832CONFIG_USB_MDC800=m
1833CONFIG_USB_MICROTEK=m
1834
1835#
1836# USB port drivers
1837#
1838CONFIG_USB_SERIAL=m
1839CONFIG_USB_EZUSB=y
1840CONFIG_USB_SERIAL_GENERIC=y
1841CONFIG_USB_SERIAL_AIRCABLE=m
1842CONFIG_USB_SERIAL_ARK3116=m
1843CONFIG_USB_SERIAL_BELKIN=m
1844CONFIG_USB_SERIAL_CH341=m
1845CONFIG_USB_SERIAL_WHITEHEAT=m
1846CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
1847CONFIG_USB_SERIAL_CP2101=m
1848CONFIG_USB_SERIAL_CYPRESS_M8=m
1849CONFIG_USB_SERIAL_EMPEG=m
1850CONFIG_USB_SERIAL_FTDI_SIO=m
1851CONFIG_USB_SERIAL_FUNSOFT=m
1852CONFIG_USB_SERIAL_VISOR=m
1853CONFIG_USB_SERIAL_IPAQ=m
1854CONFIG_USB_SERIAL_IR=m
1855CONFIG_USB_SERIAL_EDGEPORT=m
1856CONFIG_USB_SERIAL_EDGEPORT_TI=m
1857CONFIG_USB_SERIAL_GARMIN=m
1858CONFIG_USB_SERIAL_IPW=m
1859CONFIG_USB_SERIAL_IUU=m
1860CONFIG_USB_SERIAL_KEYSPAN_PDA=m
1861CONFIG_USB_SERIAL_KEYSPAN=m
1862CONFIG_USB_SERIAL_KEYSPAN_MPR=y
1863CONFIG_USB_SERIAL_KEYSPAN_USA28=y
1864CONFIG_USB_SERIAL_KEYSPAN_USA28X=y
1865CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y
1866CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y
1867CONFIG_USB_SERIAL_KEYSPAN_USA19=y
1868CONFIG_USB_SERIAL_KEYSPAN_USA18X=y
1869CONFIG_USB_SERIAL_KEYSPAN_USA19W=y
1870CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y
1871CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y
1872CONFIG_USB_SERIAL_KEYSPAN_USA49W=y
1873CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
1874CONFIG_USB_SERIAL_KLSI=m
1875CONFIG_USB_SERIAL_KOBIL_SCT=m
1876CONFIG_USB_SERIAL_MCT_U232=m
1877CONFIG_USB_SERIAL_MOS7720=m
1878CONFIG_USB_SERIAL_MOS7840=m
1879# CONFIG_USB_SERIAL_MOTOROLA is not set
1880CONFIG_USB_SERIAL_NAVMAN=m
1881CONFIG_USB_SERIAL_PL2303=m
1882CONFIG_USB_SERIAL_OTI6858=m
1883# CONFIG_USB_SERIAL_SPCP8X5 is not set
1884CONFIG_USB_SERIAL_HP4X=m
1885CONFIG_USB_SERIAL_SAFE=m
1886CONFIG_USB_SERIAL_SAFE_PADDED=y
1887CONFIG_USB_SERIAL_SIERRAWIRELESS=m
1888CONFIG_USB_SERIAL_TI=m
1889CONFIG_USB_SERIAL_CYBERJACK=m
1890CONFIG_USB_SERIAL_XIRCOM=m
1891CONFIG_USB_SERIAL_OPTION=m
1892CONFIG_USB_SERIAL_OMNINET=m
1893CONFIG_USB_SERIAL_DEBUG=m
1894
1895#
1896# USB Miscellaneous drivers
1897#
1898CONFIG_USB_EMI62=m
1899CONFIG_USB_EMI26=m
1900CONFIG_USB_ADUTUX=m
1901# CONFIG_USB_RIO500 is not set
1902CONFIG_USB_LEGOTOWER=m
1903CONFIG_USB_LCD=m
1904CONFIG_USB_BERRY_CHARGE=m
1905CONFIG_USB_LED=m
1906# CONFIG_USB_CYPRESS_CY7C63 is not set
1907# CONFIG_USB_CYTHERM is not set
1908CONFIG_USB_PHIDGET=m
1909CONFIG_USB_PHIDGETKIT=m
1910CONFIG_USB_PHIDGETMOTORCONTROL=m
1911CONFIG_USB_PHIDGETSERVO=m
1912CONFIG_USB_IDMOUSE=m
1913CONFIG_USB_FTDI_ELAN=m
1914CONFIG_USB_APPLEDISPLAY=m
1915CONFIG_USB_SISUSBVGA=m
1916CONFIG_USB_SISUSBVGA_CON=y
1917CONFIG_USB_LD=m
1918CONFIG_USB_TRANCEVIBRATOR=m
1919CONFIG_USB_IOWARRIOR=m
1920# CONFIG_USB_TEST is not set
1921# CONFIG_USB_ISIGHTFW is not set
1922# CONFIG_USB_GADGET is not set
1923CONFIG_MMC=m
1924# CONFIG_MMC_DEBUG is not set
1925# CONFIG_MMC_UNSAFE_RESUME is not set
1926
1927#
1928# MMC/SD Card Drivers
1929#
1930CONFIG_MMC_BLOCK=m
1931CONFIG_MMC_BLOCK_BOUNCE=y
1932CONFIG_SDIO_UART=m
1933# CONFIG_MMC_TEST is not set
1934
1935#
1936# MMC/SD Host Controller Drivers
1937#
1938CONFIG_MMC_SDHCI=m
1939# CONFIG_MMC_SDHCI_PCI is not set
1940CONFIG_MMC_WBSD=m
1941CONFIG_MMC_TIFM_SD=m
1942CONFIG_MEMSTICK=m
1943CONFIG_MEMSTICK_DEBUG=y
1944
1945#
1946# MemoryStick drivers
1947#
1948# CONFIG_MEMSTICK_UNSAFE_RESUME is not set
1949CONFIG_MSPRO_BLOCK=m
1950
1951#
1952# MemoryStick Host Controller Drivers
1953#
1954# CONFIG_MEMSTICK_TIFM_MS is not set
1955# CONFIG_MEMSTICK_JMICRON_38X is not set
1956CONFIG_NEW_LEDS=y
1957CONFIG_LEDS_CLASS=m
1958
1959#
1960# LED drivers
1961#
1962# CONFIG_LEDS_PCA9532 is not set
1963# CONFIG_LEDS_CLEVO_MAIL is not set
1964# CONFIG_LEDS_PCA955X is not set
1965
1966#
1967# LED Triggers
1968#
1969CONFIG_LEDS_TRIGGERS=y
1970# CONFIG_LEDS_TRIGGER_TIMER is not set
1971# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
1972# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
1973# CONFIG_ACCESSIBILITY is not set
1974# CONFIG_INFINIBAND is not set
1975# CONFIG_EDAC is not set
1976CONFIG_RTC_LIB=y
1977CONFIG_RTC_CLASS=y
1978# CONFIG_RTC_HCTOSYS is not set
1979# CONFIG_RTC_DEBUG is not set
1980
1981#
1982# RTC interfaces
1983#
1984CONFIG_RTC_INTF_SYSFS=y
1985CONFIG_RTC_INTF_PROC=y
1986CONFIG_RTC_INTF_DEV=y
1987# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
1988# CONFIG_RTC_DRV_TEST is not set
1989
1990#
1991# I2C RTC drivers
1992#
1993# CONFIG_RTC_DRV_DS1307 is not set
1994# CONFIG_RTC_DRV_DS1374 is not set
1995# CONFIG_RTC_DRV_DS1672 is not set
1996# CONFIG_RTC_DRV_MAX6900 is not set
1997# CONFIG_RTC_DRV_RS5C372 is not set
1998# CONFIG_RTC_DRV_ISL1208 is not set
1999# CONFIG_RTC_DRV_X1205 is not set
2000# CONFIG_RTC_DRV_PCF8563 is not set
2001# CONFIG_RTC_DRV_PCF8583 is not set
2002# CONFIG_RTC_DRV_M41T80 is not set
2003# CONFIG_RTC_DRV_S35390A is not set
2004# CONFIG_RTC_DRV_FM3130 is not set
2005
2006#
2007# SPI RTC drivers
2008#
2009
2010#
2011# Platform RTC drivers
2012#
2013CONFIG_RTC_DRV_CMOS=y
2014# CONFIG_RTC_DRV_DS1511 is not set
2015# CONFIG_RTC_DRV_DS1553 is not set
2016# CONFIG_RTC_DRV_DS1742 is not set
2017# CONFIG_RTC_DRV_STK17TA8 is not set
2018# CONFIG_RTC_DRV_M48T86 is not set
2019# CONFIG_RTC_DRV_M48T59 is not set
2020# CONFIG_RTC_DRV_V3020 is not set
2021
2022#
2023# on-CPU RTC drivers
2024#
2025# CONFIG_DMADEVICES is not set
2026# CONFIG_UIO is not set
2027
2028#
2029# Firmware Drivers
2030#
2031# CONFIG_EDD is not set
2032CONFIG_FIRMWARE_MEMMAP=y
2033# CONFIG_DELL_RBU is not set
2034# CONFIG_DCDBAS is not set
2035# CONFIG_DMIID is not set
2036# CONFIG_ISCSI_IBFT_FIND is not set
2037
2038#
2039# File systems
2040#
2041# CONFIG_EXT2_FS is not set
2042CONFIG_EXT3_FS=y
2043CONFIG_EXT3_FS_XATTR=y
2044CONFIG_EXT3_FS_POSIX_ACL=y
2045CONFIG_EXT3_FS_SECURITY=y
2046# CONFIG_EXT4DEV_FS is not set
2047CONFIG_JBD=y
2048# CONFIG_JBD_DEBUG is not set
2049CONFIG_FS_MBCACHE=y
2050# CONFIG_REISERFS_FS is not set
2051# CONFIG_JFS_FS is not set
2052CONFIG_FS_POSIX_ACL=y
2053# CONFIG_XFS_FS is not set
2054# CONFIG_OCFS2_FS is not set
2055CONFIG_DNOTIFY=y
2056CONFIG_INOTIFY=y
2057CONFIG_INOTIFY_USER=y
2058CONFIG_QUOTA=y
2059CONFIG_QUOTA_NETLINK_INTERFACE=y
2060# CONFIG_PRINT_QUOTA_WARNING is not set
2061# CONFIG_QFMT_V1 is not set
2062CONFIG_QFMT_V2=y
2063CONFIG_QUOTACTL=y
2064# CONFIG_AUTOFS_FS is not set
2065# CONFIG_AUTOFS4_FS is not set
2066CONFIG_FUSE_FS=m
2067CONFIG_GENERIC_ACL=y
2068
2069#
2070# CD-ROM/DVD Filesystems
2071#
2072CONFIG_ISO9660_FS=y
2073CONFIG_JOLIET=y
2074CONFIG_ZISOFS=y
2075CONFIG_UDF_FS=m
2076CONFIG_UDF_NLS=y
2077
2078#
2079# DOS/FAT/NT Filesystems
2080#
2081CONFIG_FAT_FS=y
2082CONFIG_MSDOS_FS=y
2083CONFIG_VFAT_FS=y
2084CONFIG_FAT_DEFAULT_CODEPAGE=437
2085CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
2086# CONFIG_NTFS_FS is not set
2087
2088#
2089# Pseudo filesystems
2090#
2091CONFIG_PROC_FS=y
2092CONFIG_PROC_KCORE=y
2093CONFIG_PROC_VMCORE=y
2094CONFIG_PROC_SYSCTL=y
2095CONFIG_SYSFS=y
2096CONFIG_TMPFS=y
2097CONFIG_TMPFS_POSIX_ACL=y
2098CONFIG_HUGETLBFS=y
2099CONFIG_HUGETLB_PAGE=y
2100CONFIG_CONFIGFS_FS=m
2101
2102#
2103# Miscellaneous filesystems
2104#
2105# CONFIG_ADFS_FS is not set
2106# CONFIG_AFFS_FS is not set
2107# CONFIG_ECRYPT_FS is not set
2108# CONFIG_HFS_FS is not set
2109# CONFIG_HFSPLUS_FS is not set
2110# CONFIG_BEFS_FS is not set
2111# CONFIG_BFS_FS is not set
2112# CONFIG_EFS_FS is not set
2113# CONFIG_CRAMFS is not set
2114# CONFIG_VXFS_FS is not set
2115# CONFIG_MINIX_FS is not set
2116# CONFIG_OMFS_FS is not set
2117# CONFIG_HPFS_FS is not set
2118# CONFIG_QNX4FS_FS is not set
2119# CONFIG_ROMFS_FS is not set
2120# CONFIG_SYSV_FS is not set
2121# CONFIG_UFS_FS is not set
2122CONFIG_NETWORK_FILESYSTEMS=y
2123CONFIG_NFS_FS=y
2124CONFIG_NFS_V3=y
2125# CONFIG_NFS_V3_ACL is not set
2126# CONFIG_NFS_V4 is not set
2127CONFIG_ROOT_NFS=y
2128CONFIG_NFSD=y
2129CONFIG_NFSD_V3=y
2130# CONFIG_NFSD_V3_ACL is not set
2131# CONFIG_NFSD_V4 is not set
2132CONFIG_LOCKD=y
2133CONFIG_LOCKD_V4=y
2134CONFIG_EXPORTFS=y
2135CONFIG_NFS_COMMON=y
2136CONFIG_SUNRPC=y
2137# CONFIG_RPCSEC_GSS_KRB5 is not set
2138# CONFIG_RPCSEC_GSS_SPKM3 is not set
2139# CONFIG_SMB_FS is not set
2140# CONFIG_CIFS is not set
2141# CONFIG_NCP_FS is not set
2142# CONFIG_CODA_FS is not set
2143# CONFIG_AFS_FS is not set
2144
2145#
2146# Partition Types
2147#
2148CONFIG_PARTITION_ADVANCED=y
2149# CONFIG_ACORN_PARTITION is not set
2150CONFIG_OSF_PARTITION=y
2151CONFIG_AMIGA_PARTITION=y
2152# CONFIG_ATARI_PARTITION is not set
2153CONFIG_MAC_PARTITION=y
2154CONFIG_MSDOS_PARTITION=y
2155CONFIG_BSD_DISKLABEL=y
2156CONFIG_MINIX_SUBPARTITION=y
2157CONFIG_SOLARIS_X86_PARTITION=y
2158CONFIG_UNIXWARE_DISKLABEL=y
2159# CONFIG_LDM_PARTITION is not set
2160CONFIG_SGI_PARTITION=y
2161# CONFIG_ULTRIX_PARTITION is not set
2162CONFIG_SUN_PARTITION=y
2163CONFIG_KARMA_PARTITION=y
2164CONFIG_EFI_PARTITION=y
2165# CONFIG_SYSV68_PARTITION is not set
2166CONFIG_NLS=y
2167CONFIG_NLS_DEFAULT="utf8"
2168CONFIG_NLS_CODEPAGE_437=y
2169CONFIG_NLS_CODEPAGE_737=m
2170CONFIG_NLS_CODEPAGE_775=m
2171CONFIG_NLS_CODEPAGE_850=m
2172CONFIG_NLS_CODEPAGE_852=m
2173CONFIG_NLS_CODEPAGE_855=m
2174CONFIG_NLS_CODEPAGE_857=m
2175CONFIG_NLS_CODEPAGE_860=m
2176CONFIG_NLS_CODEPAGE_861=m
2177CONFIG_NLS_CODEPAGE_862=m
2178CONFIG_NLS_CODEPAGE_863=m
2179CONFIG_NLS_CODEPAGE_864=m
2180CONFIG_NLS_CODEPAGE_865=m
2181CONFIG_NLS_CODEPAGE_866=m
2182CONFIG_NLS_CODEPAGE_869=m
2183CONFIG_NLS_CODEPAGE_936=m
2184CONFIG_NLS_CODEPAGE_950=m
2185CONFIG_NLS_CODEPAGE_932=m
2186CONFIG_NLS_CODEPAGE_949=m
2187CONFIG_NLS_CODEPAGE_874=m
2188CONFIG_NLS_ISO8859_8=m
2189CONFIG_NLS_CODEPAGE_1250=m
2190CONFIG_NLS_CODEPAGE_1251=m
2191CONFIG_NLS_ASCII=y
2192CONFIG_NLS_ISO8859_1=m
2193CONFIG_NLS_ISO8859_2=m
2194CONFIG_NLS_ISO8859_3=m
2195CONFIG_NLS_ISO8859_4=m
2196CONFIG_NLS_ISO8859_5=m
2197CONFIG_NLS_ISO8859_6=m
2198CONFIG_NLS_ISO8859_7=m
2199CONFIG_NLS_ISO8859_9=m
2200CONFIG_NLS_ISO8859_13=m
2201CONFIG_NLS_ISO8859_14=m
2202CONFIG_NLS_ISO8859_15=m
2203CONFIG_NLS_KOI8_R=m
2204CONFIG_NLS_KOI8_U=m
2205CONFIG_NLS_UTF8=m
2206# CONFIG_DLM is not set
2207
2208#
2209# Kernel hacking
2210#
2211CONFIG_TRACE_IRQFLAGS_SUPPORT=y
2212CONFIG_PRINTK_TIME=y
2213# CONFIG_ENABLE_WARN_DEPRECATED is not set
2214CONFIG_ENABLE_MUST_CHECK=y
2215CONFIG_FRAME_WARN=1024
2216CONFIG_MAGIC_SYSRQ=y
2217CONFIG_UNUSED_SYMBOLS=y
2218CONFIG_DEBUG_FS=y
2219# CONFIG_HEADERS_CHECK is not set
2220CONFIG_DEBUG_KERNEL=y
2221CONFIG_DEBUG_SHIRQ=y
2222CONFIG_DETECT_SOFTLOCKUP=y
2223# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
2224CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
2225CONFIG_SCHED_DEBUG=y
2226CONFIG_SCHEDSTATS=y
2227CONFIG_TIMER_STATS=y
2228# CONFIG_DEBUG_OBJECTS is not set
2229# CONFIG_DEBUG_SLAB is not set
2230# CONFIG_DEBUG_RT_MUTEXES is not set
2231# CONFIG_RT_MUTEX_TESTER is not set
2232# CONFIG_DEBUG_SPINLOCK is not set
2233# CONFIG_DEBUG_MUTEXES is not set
2234# CONFIG_DEBUG_LOCK_ALLOC is not set
2235# CONFIG_PROVE_LOCKING is not set
2236# CONFIG_LOCK_STAT is not set
2237CONFIG_DEBUG_SPINLOCK_SLEEP=y
2238# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
2239CONFIG_STACKTRACE=y
2240# CONFIG_DEBUG_KOBJECT is not set
2241# CONFIG_DEBUG_HIGHMEM is not set
2242CONFIG_DEBUG_BUGVERBOSE=y
2243# CONFIG_DEBUG_INFO is not set
2244# CONFIG_DEBUG_VM is not set
2245# CONFIG_DEBUG_WRITECOUNT is not set
2246CONFIG_DEBUG_MEMORY_INIT=y
2247CONFIG_DEBUG_LIST=y
2248# CONFIG_DEBUG_SG is not set
2249CONFIG_FRAME_POINTER=y
2250CONFIG_BOOT_PRINTK_DELAY=y
2251# CONFIG_RCU_TORTURE_TEST is not set
2252# CONFIG_BACKTRACE_SELF_TEST is not set
2253# CONFIG_FAULT_INJECTION is not set
2254CONFIG_LATENCYTOP=y
2255CONFIG_SYSCTL_SYSCALL_CHECK=y
2256CONFIG_HAVE_FTRACE=y
2257CONFIG_HAVE_DYNAMIC_FTRACE=y
2258CONFIG_TRACING=y
2259# CONFIG_FTRACE is not set
2260# CONFIG_IRQSOFF_TRACER is not set
2261CONFIG_SYSPROF_TRACER=y
2262# CONFIG_SCHED_TRACER is not set
2263# CONFIG_CONTEXT_SWITCH_TRACER is not set
2264# CONFIG_FTRACE_STARTUP_TEST is not set
2265# CONFIG_PROVIDE_OHCI1394_DMA_INIT is not set
2266# CONFIG_SAMPLES is not set
2267CONFIG_HAVE_ARCH_KGDB=y
2268# CONFIG_KGDB is not set
2269# CONFIG_STRICT_DEVMEM is not set
2270CONFIG_X86_VERBOSE_BOOTUP=y
2271CONFIG_EARLY_PRINTK=y
2272# CONFIG_DEBUG_STACKOVERFLOW is not set
2273# CONFIG_DEBUG_STACK_USAGE is not set
2274# CONFIG_DEBUG_PAGEALLOC is not set
2275# CONFIG_DEBUG_PER_CPU_MAPS is not set
2276CONFIG_X86_PTDUMP=y
2277CONFIG_DEBUG_RODATA=y
2278# CONFIG_DEBUG_RODATA_TEST is not set
2279# CONFIG_DEBUG_NX_TEST is not set
2280# CONFIG_4KSTACKS is not set
2281CONFIG_DOUBLEFAULT=y
2282# CONFIG_MMIOTRACE is not set
2283CONFIG_IO_DELAY_TYPE_0X80=0
2284CONFIG_IO_DELAY_TYPE_0XED=1
2285CONFIG_IO_DELAY_TYPE_UDELAY=2
2286CONFIG_IO_DELAY_TYPE_NONE=3
2287CONFIG_IO_DELAY_0X80=y
2288# CONFIG_IO_DELAY_0XED is not set
2289# CONFIG_IO_DELAY_UDELAY is not set
2290# CONFIG_IO_DELAY_NONE is not set
2291CONFIG_DEFAULT_IO_DELAY_TYPE=0
2292CONFIG_DEBUG_BOOT_PARAMS=y
2293# CONFIG_CPA_DEBUG is not set
2294# CONFIG_OPTIMIZE_INLINING is not set
2295
2296#
2297# Security options
2298#
2299CONFIG_KEYS=y
2300CONFIG_KEYS_DEBUG_PROC_KEYS=y
2301CONFIG_SECURITY=y
2302CONFIG_SECURITY_NETWORK=y
2303CONFIG_SECURITY_NETWORK_XFRM=y
2304CONFIG_SECURITY_FILE_CAPABILITIES=y
2305# CONFIG_SECURITY_ROOTPLUG is not set
2306CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=65536
2307# CONFIG_SECURITY_SELINUX is not set
2308# CONFIG_SECURITY_SMACK is not set
2309CONFIG_CRYPTO=y
2310
2311#
2312# Crypto core or helper
2313#
2314CONFIG_CRYPTO_ALGAPI=y
2315CONFIG_CRYPTO_AEAD=m
2316CONFIG_CRYPTO_BLKCIPHER=m
2317CONFIG_CRYPTO_HASH=y
2318CONFIG_CRYPTO_MANAGER=y
2319CONFIG_CRYPTO_GF128MUL=m
2320CONFIG_CRYPTO_NULL=m
2321# CONFIG_CRYPTO_CRYPTD is not set
2322CONFIG_CRYPTO_AUTHENC=m
2323CONFIG_CRYPTO_TEST=m
2324
2325#
2326# Authenticated Encryption with Associated Data
2327#
2328CONFIG_CRYPTO_CCM=m
2329CONFIG_CRYPTO_GCM=m
2330CONFIG_CRYPTO_SEQIV=m
2331
2332#
2333# Block modes
2334#
2335CONFIG_CRYPTO_CBC=m
2336CONFIG_CRYPTO_CTR=m
2337# CONFIG_CRYPTO_CTS is not set
2338CONFIG_CRYPTO_ECB=m
2339CONFIG_CRYPTO_LRW=m
2340CONFIG_CRYPTO_PCBC=m
2341CONFIG_CRYPTO_XTS=m
2342
2343#
2344# Hash modes
2345#
2346CONFIG_CRYPTO_HMAC=y
2347CONFIG_CRYPTO_XCBC=m
2348
2349#
2350# Digest
2351#
2352CONFIG_CRYPTO_CRC32C=m
2353CONFIG_CRYPTO_MD4=m
2354CONFIG_CRYPTO_MD5=y
2355CONFIG_CRYPTO_MICHAEL_MIC=m
2356# CONFIG_CRYPTO_RMD128 is not set
2357# CONFIG_CRYPTO_RMD160 is not set
2358# CONFIG_CRYPTO_RMD256 is not set
2359# CONFIG_CRYPTO_RMD320 is not set
2360CONFIG_CRYPTO_SHA1=y
2361CONFIG_CRYPTO_SHA256=m
2362CONFIG_CRYPTO_SHA512=m
2363CONFIG_CRYPTO_TGR192=m
2364CONFIG_CRYPTO_WP512=m
2365
2366#
2367# Ciphers
2368#
2369CONFIG_CRYPTO_AES=m
2370# CONFIG_CRYPTO_AES_586 is not set
2371CONFIG_CRYPTO_ANUBIS=m
2372CONFIG_CRYPTO_ARC4=m
2373CONFIG_CRYPTO_BLOWFISH=m
2374CONFIG_CRYPTO_CAMELLIA=m
2375CONFIG_CRYPTO_CAST5=m
2376CONFIG_CRYPTO_CAST6=m
2377CONFIG_CRYPTO_DES=m
2378CONFIG_CRYPTO_FCRYPT=m
2379CONFIG_CRYPTO_KHAZAD=m
2380CONFIG_CRYPTO_SALSA20=m
2381# CONFIG_CRYPTO_SALSA20_586 is not set
2382CONFIG_CRYPTO_SEED=m
2383CONFIG_CRYPTO_SERPENT=m
2384CONFIG_CRYPTO_TEA=m
2385CONFIG_CRYPTO_TWOFISH=m
2386CONFIG_CRYPTO_TWOFISH_COMMON=m
2387# CONFIG_CRYPTO_TWOFISH_586 is not set
2388
2389#
2390# Compression
2391#
2392CONFIG_CRYPTO_DEFLATE=m
2393# CONFIG_CRYPTO_LZO is not set
2394CONFIG_CRYPTO_HW=y
2395# CONFIG_CRYPTO_DEV_PADLOCK is not set
2396# CONFIG_CRYPTO_DEV_GEODE is not set
2397# CONFIG_CRYPTO_DEV_HIFN_795X is not set
2398CONFIG_HAVE_KVM=y
2399# CONFIG_VIRTUALIZATION is not set
2400
2401#
2402# Library routines
2403#
2404CONFIG_BITREVERSE=y
2405CONFIG_GENERIC_FIND_FIRST_BIT=y
2406CONFIG_GENERIC_FIND_NEXT_BIT=y
2407CONFIG_CRC_CCITT=m
2408CONFIG_CRC16=m
2409CONFIG_CRC_T10DIF=y
2410CONFIG_CRC_ITU_T=m
2411CONFIG_CRC32=y
2412# CONFIG_CRC7 is not set
2413CONFIG_LIBCRC32C=m
2414CONFIG_AUDIT_GENERIC=y
2415CONFIG_ZLIB_INFLATE=y
2416CONFIG_ZLIB_DEFLATE=m
2417CONFIG_TEXTSEARCH=y
2418CONFIG_TEXTSEARCH_KMP=m
2419CONFIG_TEXTSEARCH_BM=m
2420CONFIG_TEXTSEARCH_FSM=m
2421CONFIG_PLIST=y
2422CONFIG_HAS_IOMEM=y
2423CONFIG_HAS_IOPORT=y
2424CONFIG_HAS_DMA=y
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/defconfig-netbook b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/defconfig-netbook
new file mode 100644
index 0000000000..ad9729e88d
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27-rc6/defconfig-netbook
@@ -0,0 +1,2424 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.27-rc6
4# Thu Oct 9 20:10:11 2008
5#
6# CONFIG_64BIT is not set
7CONFIG_X86_32=y
8# CONFIG_X86_64 is not set
9CONFIG_X86=y
10CONFIG_ARCH_DEFCONFIG="arch/x86/configs/i386_defconfig"
11# CONFIG_GENERIC_LOCKBREAK is not set
12CONFIG_GENERIC_TIME=y
13CONFIG_GENERIC_CMOS_UPDATE=y
14CONFIG_CLOCKSOURCE_WATCHDOG=y
15CONFIG_GENERIC_CLOCKEVENTS=y
16CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
17CONFIG_LOCKDEP_SUPPORT=y
18CONFIG_STACKTRACE_SUPPORT=y
19CONFIG_HAVE_LATENCYTOP_SUPPORT=y
20CONFIG_FAST_CMPXCHG_LOCAL=y
21CONFIG_MMU=y
22CONFIG_ZONE_DMA=y
23CONFIG_GENERIC_ISA_DMA=y
24CONFIG_GENERIC_IOMAP=y
25CONFIG_GENERIC_BUG=y
26CONFIG_GENERIC_HWEIGHT=y
27# CONFIG_GENERIC_GPIO is not set
28CONFIG_ARCH_MAY_HAVE_PC_FDC=y
29# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
30CONFIG_RWSEM_XCHGADD_ALGORITHM=y
31# CONFIG_ARCH_HAS_ILOG2_U32 is not set
32# CONFIG_ARCH_HAS_ILOG2_U64 is not set
33CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
34CONFIG_GENERIC_CALIBRATE_DELAY=y
35# CONFIG_GENERIC_TIME_VSYSCALL is not set
36CONFIG_ARCH_HAS_CPU_RELAX=y
37CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y
38CONFIG_HAVE_SETUP_PER_CPU_AREA=y
39# CONFIG_HAVE_CPUMASK_OF_CPU_MAP is not set
40CONFIG_ARCH_HIBERNATION_POSSIBLE=y
41CONFIG_ARCH_SUSPEND_POSSIBLE=y
42# CONFIG_ZONE_DMA32 is not set
43CONFIG_ARCH_POPULATES_NODE_MAP=y
44# CONFIG_AUDIT_ARCH is not set
45CONFIG_ARCH_SUPPORTS_AOUT=y
46CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING=y
47CONFIG_GENERIC_HARDIRQS=y
48CONFIG_GENERIC_IRQ_PROBE=y
49CONFIG_GENERIC_PENDING_IRQ=y
50CONFIG_X86_SMP=y
51CONFIG_X86_32_SMP=y
52CONFIG_X86_HT=y
53CONFIG_X86_BIOS_REBOOT=y
54CONFIG_X86_TRAMPOLINE=y
55CONFIG_KTIME_SCALAR=y
56CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
57
58#
59# General setup
60#
61CONFIG_EXPERIMENTAL=y
62CONFIG_LOCK_KERNEL=y
63CONFIG_INIT_ENV_ARG_LIMIT=32
64CONFIG_LOCALVERSION="-netbook"
65# CONFIG_LOCALVERSION_AUTO is not set
66CONFIG_SWAP=y
67CONFIG_SYSVIPC=y
68CONFIG_SYSVIPC_SYSCTL=y
69CONFIG_POSIX_MQUEUE=y
70CONFIG_BSD_PROCESS_ACCT=y
71CONFIG_BSD_PROCESS_ACCT_V3=y
72CONFIG_TASKSTATS=y
73CONFIG_TASK_DELAY_ACCT=y
74CONFIG_TASK_XACCT=y
75CONFIG_TASK_IO_ACCOUNTING=y
76CONFIG_AUDIT=y
77CONFIG_AUDITSYSCALL=y
78CONFIG_AUDIT_TREE=y
79CONFIG_IKCONFIG=y
80CONFIG_IKCONFIG_PROC=y
81CONFIG_LOG_BUF_SHIFT=17
82# CONFIG_CGROUPS is not set
83CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y
84# CONFIG_GROUP_SCHED is not set
85# CONFIG_SYSFS_DEPRECATED_V2 is not set
86CONFIG_RELAY=y
87CONFIG_NAMESPACES=y
88# CONFIG_UTS_NS is not set
89# CONFIG_IPC_NS is not set
90CONFIG_USER_NS=y
91# CONFIG_PID_NS is not set
92CONFIG_BLK_DEV_INITRD=y
93CONFIG_INITRAMFS_SOURCE=""
94CONFIG_CC_OPTIMIZE_FOR_SIZE=y
95CONFIG_FASTBOOT=y
96CONFIG_SYSCTL=y
97# CONFIG_EMBEDDED is not set
98CONFIG_UID16=y
99CONFIG_SYSCTL_SYSCALL=y
100CONFIG_KALLSYMS=y
101CONFIG_KALLSYMS_ALL=y
102CONFIG_KALLSYMS_EXTRA_PASS=y
103CONFIG_HOTPLUG=y
104CONFIG_PRINTK=y
105CONFIG_BUG=y
106CONFIG_ELF_CORE=y
107CONFIG_PCSPKR_PLATFORM=y
108# CONFIG_COMPAT_BRK is not set
109CONFIG_BASE_FULL=y
110CONFIG_FUTEX=y
111CONFIG_ANON_INODES=y
112CONFIG_EPOLL=y
113CONFIG_SIGNALFD=y
114CONFIG_TIMERFD=y
115CONFIG_EVENTFD=y
116CONFIG_SHMEM=y
117CONFIG_VM_EVENT_COUNTERS=y
118CONFIG_SLAB=y
119# CONFIG_SLUB is not set
120# CONFIG_SLOB is not set
121CONFIG_PROFILING=y
122# CONFIG_MARKERS is not set
123# CONFIG_OPROFILE is not set
124CONFIG_HAVE_OPROFILE=y
125# CONFIG_KPROBES is not set
126CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
127CONFIG_HAVE_IOREMAP_PROT=y
128CONFIG_HAVE_KPROBES=y
129CONFIG_HAVE_KRETPROBES=y
130# CONFIG_HAVE_ARCH_TRACEHOOK is not set
131# CONFIG_HAVE_DMA_ATTRS is not set
132CONFIG_USE_GENERIC_SMP_HELPERS=y
133# CONFIG_HAVE_CLK is not set
134CONFIG_PROC_PAGE_MONITOR=y
135CONFIG_HAVE_GENERIC_DMA_COHERENT=y
136CONFIG_SLABINFO=y
137CONFIG_RT_MUTEXES=y
138# CONFIG_TINY_SHMEM is not set
139CONFIG_BASE_SMALL=0
140CONFIG_MODULES=y
141# CONFIG_MODULE_FORCE_LOAD is not set
142CONFIG_MODULE_UNLOAD=y
143# CONFIG_MODULE_FORCE_UNLOAD is not set
144# CONFIG_MODVERSIONS is not set
145# CONFIG_MODULE_SRCVERSION_ALL is not set
146CONFIG_KMOD=y
147CONFIG_STOP_MACHINE=y
148CONFIG_BLOCK=y
149# CONFIG_LBD is not set
150CONFIG_BLK_DEV_IO_TRACE=y
151# CONFIG_LSF is not set
152CONFIG_BLK_DEV_BSG=y
153# CONFIG_BLK_DEV_INTEGRITY is not set
154
155#
156# IO Schedulers
157#
158CONFIG_IOSCHED_NOOP=y
159# CONFIG_IOSCHED_AS is not set
160# CONFIG_IOSCHED_DEADLINE is not set
161CONFIG_IOSCHED_CFQ=y
162# CONFIG_DEFAULT_AS is not set
163# CONFIG_DEFAULT_DEADLINE is not set
164CONFIG_DEFAULT_CFQ=y
165# CONFIG_DEFAULT_NOOP is not set
166CONFIG_DEFAULT_IOSCHED="cfq"
167CONFIG_CLASSIC_RCU=y
168
169#
170# Processor type and features
171#
172CONFIG_TICK_ONESHOT=y
173CONFIG_NO_HZ=y
174CONFIG_HIGH_RES_TIMERS=y
175CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
176CONFIG_SMP=y
177CONFIG_X86_FIND_SMP_CONFIG=y
178CONFIG_X86_MPPARSE=y
179CONFIG_X86_PC=y
180# CONFIG_X86_ELAN is not set
181# CONFIG_X86_VOYAGER is not set
182# CONFIG_X86_GENERICARCH is not set
183# CONFIG_X86_VSMP is not set
184# CONFIG_X86_RDC321X is not set
185CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
186# CONFIG_PARAVIRT_GUEST is not set
187# CONFIG_MEMTEST is not set
188# CONFIG_M386 is not set
189# CONFIG_M486 is not set
190# CONFIG_M586 is not set
191# CONFIG_M586TSC is not set
192# CONFIG_M586MMX is not set
193CONFIG_M686=y
194# CONFIG_MPENTIUMII is not set
195# CONFIG_MPENTIUMIII is not set
196# CONFIG_MPENTIUMM is not set
197# CONFIG_MPENTIUM4 is not set
198# CONFIG_MK6 is not set
199# CONFIG_MK7 is not set
200# CONFIG_MK8 is not set
201# CONFIG_MCRUSOE is not set
202# CONFIG_MEFFICEON is not set
203# CONFIG_MWINCHIPC6 is not set
204# CONFIG_MWINCHIP2 is not set
205# CONFIG_MWINCHIP3D is not set
206# CONFIG_MGEODEGX1 is not set
207# CONFIG_MGEODE_LX is not set
208# CONFIG_MCYRIXIII is not set
209# CONFIG_MVIAC3_2 is not set
210# CONFIG_MVIAC7 is not set
211# CONFIG_MPSC is not set
212# CONFIG_MCORE2 is not set
213# CONFIG_GENERIC_CPU is not set
214# CONFIG_X86_GENERIC is not set
215CONFIG_X86_CPU=y
216CONFIG_X86_CMPXCHG=y
217CONFIG_X86_L1_CACHE_SHIFT=5
218CONFIG_X86_XADD=y
219# CONFIG_X86_PPRO_FENCE is not set
220CONFIG_X86_WP_WORKS_OK=y
221CONFIG_X86_INVLPG=y
222CONFIG_X86_BSWAP=y
223CONFIG_X86_POPAD_OK=y
224CONFIG_X86_USE_PPRO_CHECKSUM=y
225CONFIG_X86_TSC=y
226CONFIG_X86_CMOV=y
227CONFIG_X86_MINIMUM_CPU_FAMILY=4
228CONFIG_X86_DEBUGCTLMSR=y
229CONFIG_HPET_TIMER=y
230CONFIG_HPET_EMULATE_RTC=y
231CONFIG_DMI=y
232# CONFIG_IOMMU_HELPER is not set
233CONFIG_NR_CPUS=2
234CONFIG_SCHED_SMT=y
235CONFIG_SCHED_MC=y
236# CONFIG_PREEMPT_NONE is not set
237CONFIG_PREEMPT_VOLUNTARY=y
238# CONFIG_PREEMPT is not set
239CONFIG_X86_LOCAL_APIC=y
240CONFIG_X86_IO_APIC=y
241CONFIG_X86_MCE=y
242# CONFIG_X86_MCE_NONFATAL is not set
243# CONFIG_X86_MCE_P4THERMAL is not set
244CONFIG_VM86=y
245# CONFIG_TOSHIBA is not set
246# CONFIG_I8K is not set
247# CONFIG_X86_REBOOTFIXUPS is not set
248CONFIG_MICROCODE=y
249CONFIG_MICROCODE_OLD_INTERFACE=y
250CONFIG_X86_MSR=y
251CONFIG_X86_CPUID=y
252# CONFIG_NOHIGHMEM is not set
253CONFIG_HIGHMEM4G=y
254# CONFIG_HIGHMEM64G is not set
255CONFIG_PAGE_OFFSET=0xC0000000
256CONFIG_HIGHMEM=y
257CONFIG_NEED_NODE_MEMMAP_SIZE=y
258CONFIG_ARCH_FLATMEM_ENABLE=y
259CONFIG_ARCH_SPARSEMEM_ENABLE=y
260CONFIG_ARCH_SELECT_MEMORY_MODEL=y
261CONFIG_SELECT_MEMORY_MODEL=y
262# CONFIG_FLATMEM_MANUAL is not set
263# CONFIG_DISCONTIGMEM_MANUAL is not set
264CONFIG_SPARSEMEM_MANUAL=y
265CONFIG_SPARSEMEM=y
266CONFIG_HAVE_MEMORY_PRESENT=y
267CONFIG_SPARSEMEM_STATIC=y
268# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
269
270#
271# Memory hotplug is currently incompatible with Software Suspend
272#
273CONFIG_PAGEFLAGS_EXTENDED=y
274CONFIG_SPLIT_PTLOCK_CPUS=4
275CONFIG_RESOURCES_64BIT=y
276CONFIG_ZONE_DMA_FLAG=1
277CONFIG_BOUNCE=y
278CONFIG_VIRT_TO_BUS=y
279# CONFIG_HIGHPTE is not set
280# CONFIG_MATH_EMULATION is not set
281CONFIG_MTRR=y
282# CONFIG_MTRR_SANITIZER is not set
283# CONFIG_X86_PAT is not set
284# CONFIG_EFI is not set
285# CONFIG_IRQBALANCE is not set
286# CONFIG_SECCOMP is not set
287# CONFIG_HZ_100 is not set
288# CONFIG_HZ_250 is not set
289# CONFIG_HZ_300 is not set
290CONFIG_HZ_1000=y
291CONFIG_HZ=1000
292CONFIG_SCHED_HRTICK=y
293CONFIG_KEXEC=y
294CONFIG_CRASH_DUMP=y
295# CONFIG_KEXEC_JUMP is not set
296CONFIG_PHYSICAL_START=0x400000
297CONFIG_RELOCATABLE=y
298CONFIG_PHYSICAL_ALIGN=0x200000
299CONFIG_HOTPLUG_CPU=y
300CONFIG_COMPAT_VDSO=y
301CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
302
303#
304# Power management options
305#
306CONFIG_PM=y
307CONFIG_PM_DEBUG=y
308# CONFIG_PM_VERBOSE is not set
309CONFIG_CAN_PM_TRACE=y
310CONFIG_PM_TRACE=y
311CONFIG_PM_TRACE_RTC=y
312CONFIG_PM_SLEEP_SMP=y
313CONFIG_PM_SLEEP=y
314CONFIG_SUSPEND=y
315# CONFIG_PM_TEST_SUSPEND is not set
316CONFIG_SUSPEND_FREEZER=y
317CONFIG_HIBERNATION=y
318CONFIG_PM_STD_PARTITION=""
319CONFIG_ACPI=y
320CONFIG_ACPI_SLEEP=y
321CONFIG_ACPI_PROCFS=y
322CONFIG_ACPI_PROCFS_POWER=y
323CONFIG_ACPI_SYSFS_POWER=y
324CONFIG_ACPI_PROC_EVENT=y
325CONFIG_ACPI_AC=y
326CONFIG_ACPI_BATTERY=m
327CONFIG_ACPI_BUTTON=y
328CONFIG_ACPI_VIDEO=y
329CONFIG_ACPI_FAN=y
330CONFIG_ACPI_DOCK=y
331# CONFIG_ACPI_BAY is not set
332CONFIG_ACPI_PROCESSOR=y
333CONFIG_ACPI_HOTPLUG_CPU=y
334CONFIG_ACPI_THERMAL=y
335CONFIG_ACPI_WMI=m
336CONFIG_ACPI_ASUS=y
337# CONFIG_ACPI_TOSHIBA is not set
338# CONFIG_ACPI_CUSTOM_DSDT is not set
339CONFIG_ACPI_BLACKLIST_YEAR=0
340# CONFIG_ACPI_DEBUG is not set
341CONFIG_ACPI_EC=y
342# CONFIG_ACPI_PCI_SLOT is not set
343CONFIG_ACPI_POWER=y
344CONFIG_ACPI_SYSTEM=y
345CONFIG_X86_PM_TIMER=y
346CONFIG_ACPI_CONTAINER=y
347CONFIG_ACPI_SBS=m
348# CONFIG_APM is not set
349
350#
351# CPU Frequency scaling
352#
353CONFIG_CPU_FREQ=y
354CONFIG_CPU_FREQ_TABLE=y
355CONFIG_CPU_FREQ_DEBUG=y
356CONFIG_CPU_FREQ_STAT=m
357CONFIG_CPU_FREQ_STAT_DETAILS=y
358CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
359# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
360# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
361# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
362# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
363CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
364# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
365CONFIG_CPU_FREQ_GOV_USERSPACE=y
366CONFIG_CPU_FREQ_GOV_ONDEMAND=y
367# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
368
369#
370# CPUFreq processor drivers
371#
372CONFIG_X86_ACPI_CPUFREQ=y
373# CONFIG_X86_POWERNOW_K6 is not set
374# CONFIG_X86_POWERNOW_K7 is not set
375# CONFIG_X86_POWERNOW_K8 is not set
376# CONFIG_X86_GX_SUSPMOD is not set
377# CONFIG_X86_SPEEDSTEP_CENTRINO is not set
378# CONFIG_X86_SPEEDSTEP_ICH is not set
379# CONFIG_X86_SPEEDSTEP_SMI is not set
380# CONFIG_X86_P4_CLOCKMOD is not set
381# CONFIG_X86_CPUFREQ_NFORCE2 is not set
382# CONFIG_X86_LONGRUN is not set
383# CONFIG_X86_LONGHAUL is not set
384# CONFIG_X86_E_POWERSAVER is not set
385
386#
387# shared options
388#
389# CONFIG_X86_ACPI_CPUFREQ_PROC_INTF is not set
390# CONFIG_X86_SPEEDSTEP_LIB is not set
391CONFIG_CPU_IDLE=y
392CONFIG_CPU_IDLE_GOV_LADDER=y
393CONFIG_CPU_IDLE_GOV_MENU=y
394
395#
396# Bus options (PCI etc.)
397#
398CONFIG_PCI=y
399# CONFIG_PCI_GOBIOS is not set
400# CONFIG_PCI_GOMMCONFIG is not set
401# CONFIG_PCI_GODIRECT is not set
402# CONFIG_PCI_GOOLPC is not set
403CONFIG_PCI_GOANY=y
404CONFIG_PCI_BIOS=y
405CONFIG_PCI_DIRECT=y
406CONFIG_PCI_MMCONFIG=y
407CONFIG_PCI_DOMAINS=y
408CONFIG_PCIEPORTBUS=y
409CONFIG_PCIEAER=y
410CONFIG_PCIEASPM=y
411# CONFIG_PCIEASPM_DEBUG is not set
412CONFIG_ARCH_SUPPORTS_MSI=y
413CONFIG_PCI_MSI=y
414CONFIG_PCI_LEGACY=y
415# CONFIG_PCI_DEBUG is not set
416CONFIG_HT_IRQ=y
417CONFIG_ISA_DMA_API=y
418# CONFIG_ISA is not set
419# CONFIG_MCA is not set
420# CONFIG_SCx200 is not set
421# CONFIG_OLPC is not set
422CONFIG_K8_NB=y
423# CONFIG_PCCARD is not set
424# CONFIG_HOTPLUG_PCI is not set
425
426#
427# Executable file formats / Emulations
428#
429CONFIG_BINFMT_ELF=y
430# CONFIG_BINFMT_AOUT is not set
431CONFIG_BINFMT_MISC=y
432CONFIG_NET=y
433
434#
435# Networking options
436#
437CONFIG_PACKET=y
438CONFIG_PACKET_MMAP=y
439CONFIG_UNIX=y
440CONFIG_XFRM=y
441CONFIG_XFRM_USER=y
442CONFIG_XFRM_SUB_POLICY=y
443CONFIG_XFRM_MIGRATE=y
444CONFIG_XFRM_STATISTICS=y
445CONFIG_XFRM_IPCOMP=m
446CONFIG_NET_KEY=m
447CONFIG_NET_KEY_MIGRATE=y
448CONFIG_INET=y
449CONFIG_IP_MULTICAST=y
450# CONFIG_IP_ADVANCED_ROUTER is not set
451CONFIG_IP_FIB_HASH=y
452CONFIG_IP_PNP=y
453CONFIG_IP_PNP_DHCP=y
454# CONFIG_IP_PNP_BOOTP is not set
455# CONFIG_IP_PNP_RARP is not set
456# CONFIG_NET_IPIP is not set
457# CONFIG_NET_IPGRE is not set
458CONFIG_IP_MROUTE=y
459CONFIG_IP_PIMSM_V1=y
460CONFIG_IP_PIMSM_V2=y
461# CONFIG_ARPD is not set
462CONFIG_SYN_COOKIES=y
463CONFIG_INET_AH=m
464CONFIG_INET_ESP=m
465CONFIG_INET_IPCOMP=m
466CONFIG_INET_XFRM_TUNNEL=m
467CONFIG_INET_TUNNEL=m
468CONFIG_INET_XFRM_MODE_TRANSPORT=m
469CONFIG_INET_XFRM_MODE_TUNNEL=m
470CONFIG_INET_XFRM_MODE_BEET=m
471CONFIG_INET_LRO=y
472CONFIG_INET_DIAG=m
473CONFIG_INET_TCP_DIAG=m
474CONFIG_TCP_CONG_ADVANCED=y
475CONFIG_TCP_CONG_BIC=m
476CONFIG_TCP_CONG_CUBIC=y
477# CONFIG_TCP_CONG_WESTWOOD is not set
478# CONFIG_TCP_CONG_HTCP is not set
479# CONFIG_TCP_CONG_HSTCP is not set
480# CONFIG_TCP_CONG_HYBLA is not set
481# CONFIG_TCP_CONG_VEGAS is not set
482# CONFIG_TCP_CONG_SCALABLE is not set
483# CONFIG_TCP_CONG_LP is not set
484# CONFIG_TCP_CONG_VENO is not set
485# CONFIG_TCP_CONG_YEAH is not set
486# CONFIG_TCP_CONG_ILLINOIS is not set
487# CONFIG_DEFAULT_BIC is not set
488CONFIG_DEFAULT_CUBIC=y
489# CONFIG_DEFAULT_HTCP is not set
490# CONFIG_DEFAULT_VEGAS is not set
491# CONFIG_DEFAULT_WESTWOOD is not set
492# CONFIG_DEFAULT_RENO is not set
493CONFIG_DEFAULT_TCP_CONG="cubic"
494CONFIG_TCP_MD5SIG=y
495# CONFIG_IP_VS is not set
496CONFIG_IPV6=y
497CONFIG_IPV6_PRIVACY=y
498CONFIG_IPV6_ROUTER_PREF=y
499CONFIG_IPV6_ROUTE_INFO=y
500CONFIG_IPV6_OPTIMISTIC_DAD=y
501CONFIG_INET6_AH=m
502CONFIG_INET6_ESP=m
503CONFIG_INET6_IPCOMP=m
504CONFIG_IPV6_MIP6=m
505CONFIG_INET6_XFRM_TUNNEL=m
506CONFIG_INET6_TUNNEL=m
507CONFIG_INET6_XFRM_MODE_TRANSPORT=m
508CONFIG_INET6_XFRM_MODE_TUNNEL=m
509CONFIG_INET6_XFRM_MODE_BEET=m
510CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
511CONFIG_IPV6_SIT=m
512CONFIG_IPV6_NDISC_NODETYPE=y
513CONFIG_IPV6_TUNNEL=m
514CONFIG_IPV6_MULTIPLE_TABLES=y
515CONFIG_IPV6_SUBTREES=y
516# CONFIG_IPV6_MROUTE is not set
517CONFIG_NETLABEL=y
518CONFIG_NETWORK_SECMARK=y
519CONFIG_NETFILTER=y
520# CONFIG_NETFILTER_DEBUG is not set
521CONFIG_NETFILTER_ADVANCED=y
522
523#
524# Core Netfilter Configuration
525#
526CONFIG_NETFILTER_NETLINK=m
527CONFIG_NETFILTER_NETLINK_QUEUE=m
528CONFIG_NETFILTER_NETLINK_LOG=m
529CONFIG_NF_CONNTRACK=y
530CONFIG_NF_CT_ACCT=y
531CONFIG_NF_CONNTRACK_MARK=y
532CONFIG_NF_CONNTRACK_SECMARK=y
533CONFIG_NF_CONNTRACK_EVENTS=y
534# CONFIG_NF_CT_PROTO_DCCP is not set
535CONFIG_NF_CT_PROTO_GRE=m
536CONFIG_NF_CT_PROTO_SCTP=m
537CONFIG_NF_CT_PROTO_UDPLITE=m
538CONFIG_NF_CONNTRACK_AMANDA=m
539CONFIG_NF_CONNTRACK_FTP=m
540CONFIG_NF_CONNTRACK_H323=m
541CONFIG_NF_CONNTRACK_IRC=m
542CONFIG_NF_CONNTRACK_NETBIOS_NS=m
543CONFIG_NF_CONNTRACK_PPTP=m
544CONFIG_NF_CONNTRACK_SANE=m
545CONFIG_NF_CONNTRACK_SIP=m
546CONFIG_NF_CONNTRACK_TFTP=m
547CONFIG_NF_CT_NETLINK=m
548CONFIG_NETFILTER_XTABLES=y
549CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
550CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
551CONFIG_NETFILTER_XT_TARGET_DSCP=m
552CONFIG_NETFILTER_XT_TARGET_MARK=m
553CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
554CONFIG_NETFILTER_XT_TARGET_NFLOG=m
555CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
556CONFIG_NETFILTER_XT_TARGET_RATEEST=m
557CONFIG_NETFILTER_XT_TARGET_TRACE=m
558CONFIG_NETFILTER_XT_TARGET_SECMARK=m
559CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
560CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
561CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
562CONFIG_NETFILTER_XT_MATCH_COMMENT=m
563CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
564CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
565CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
566CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
567# CONFIG_NETFILTER_XT_MATCH_DCCP is not set
568CONFIG_NETFILTER_XT_MATCH_DSCP=m
569CONFIG_NETFILTER_XT_MATCH_ESP=m
570CONFIG_NETFILTER_XT_MATCH_HELPER=m
571CONFIG_NETFILTER_XT_MATCH_IPRANGE=m
572CONFIG_NETFILTER_XT_MATCH_LENGTH=m
573CONFIG_NETFILTER_XT_MATCH_LIMIT=m
574CONFIG_NETFILTER_XT_MATCH_MAC=m
575CONFIG_NETFILTER_XT_MATCH_MARK=m
576CONFIG_NETFILTER_XT_MATCH_OWNER=m
577CONFIG_NETFILTER_XT_MATCH_POLICY=m
578CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
579CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
580CONFIG_NETFILTER_XT_MATCH_QUOTA=m
581CONFIG_NETFILTER_XT_MATCH_RATEEST=m
582CONFIG_NETFILTER_XT_MATCH_REALM=m
583CONFIG_NETFILTER_XT_MATCH_SCTP=m
584CONFIG_NETFILTER_XT_MATCH_STATE=y
585CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
586CONFIG_NETFILTER_XT_MATCH_STRING=m
587CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
588CONFIG_NETFILTER_XT_MATCH_TIME=m
589CONFIG_NETFILTER_XT_MATCH_U32=m
590CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
591
592#
593# IP: Netfilter Configuration
594#
595CONFIG_NF_CONNTRACK_IPV4=y
596# CONFIG_NF_CONNTRACK_PROC_COMPAT is not set
597CONFIG_IP_NF_QUEUE=m
598CONFIG_IP_NF_IPTABLES=y
599CONFIG_IP_NF_MATCH_RECENT=m
600CONFIG_IP_NF_MATCH_ECN=m
601CONFIG_IP_NF_MATCH_AH=m
602CONFIG_IP_NF_MATCH_TTL=m
603CONFIG_IP_NF_MATCH_ADDRTYPE=m
604CONFIG_IP_NF_FILTER=y
605CONFIG_IP_NF_TARGET_REJECT=y
606CONFIG_IP_NF_TARGET_LOG=m
607CONFIG_IP_NF_TARGET_ULOG=m
608CONFIG_NF_NAT=m
609CONFIG_NF_NAT_NEEDED=y
610CONFIG_IP_NF_TARGET_MASQUERADE=m
611CONFIG_IP_NF_TARGET_REDIRECT=m
612CONFIG_IP_NF_TARGET_NETMAP=m
613CONFIG_NF_NAT_SNMP_BASIC=m
614CONFIG_NF_NAT_PROTO_GRE=m
615CONFIG_NF_NAT_PROTO_UDPLITE=m
616CONFIG_NF_NAT_PROTO_SCTP=m
617CONFIG_NF_NAT_FTP=m
618CONFIG_NF_NAT_IRC=m
619CONFIG_NF_NAT_TFTP=m
620CONFIG_NF_NAT_AMANDA=m
621CONFIG_NF_NAT_PPTP=m
622CONFIG_NF_NAT_H323=m
623CONFIG_NF_NAT_SIP=m
624CONFIG_IP_NF_MANGLE=m
625CONFIG_IP_NF_TARGET_ECN=m
626CONFIG_IP_NF_TARGET_TTL=m
627CONFIG_IP_NF_TARGET_CLUSTERIP=m
628CONFIG_IP_NF_RAW=m
629# CONFIG_IP_NF_SECURITY is not set
630CONFIG_IP_NF_ARPTABLES=m
631CONFIG_IP_NF_ARPFILTER=m
632CONFIG_IP_NF_ARP_MANGLE=m
633
634#
635# IPv6: Netfilter Configuration
636#
637CONFIG_NF_CONNTRACK_IPV6=y
638CONFIG_IP6_NF_QUEUE=m
639CONFIG_IP6_NF_IPTABLES=y
640CONFIG_IP6_NF_MATCH_RT=m
641CONFIG_IP6_NF_MATCH_OPTS=m
642CONFIG_IP6_NF_MATCH_FRAG=m
643CONFIG_IP6_NF_MATCH_HL=m
644CONFIG_IP6_NF_MATCH_IPV6HEADER=m
645CONFIG_IP6_NF_MATCH_AH=m
646CONFIG_IP6_NF_MATCH_MH=m
647CONFIG_IP6_NF_MATCH_EUI64=m
648CONFIG_IP6_NF_FILTER=y
649CONFIG_IP6_NF_TARGET_LOG=m
650CONFIG_IP6_NF_TARGET_REJECT=y
651CONFIG_IP6_NF_MANGLE=m
652CONFIG_IP6_NF_TARGET_HL=m
653CONFIG_IP6_NF_RAW=m
654# CONFIG_IP6_NF_SECURITY is not set
655# CONFIG_IP_DCCP is not set
656# CONFIG_IP_SCTP is not set
657# CONFIG_TIPC is not set
658# CONFIG_ATM is not set
659# CONFIG_BRIDGE is not set
660# CONFIG_VLAN_8021Q is not set
661# CONFIG_DECNET is not set
662# CONFIG_LLC2 is not set
663# CONFIG_IPX is not set
664# CONFIG_ATALK is not set
665# CONFIG_X25 is not set
666# CONFIG_LAPB is not set
667# CONFIG_ECONET is not set
668# CONFIG_WAN_ROUTER is not set
669# CONFIG_NET_SCHED is not set
670CONFIG_NET_CLS_ROUTE=y
671
672#
673# Network testing
674#
675# CONFIG_NET_PKTGEN is not set
676# CONFIG_HAMRADIO is not set
677# CONFIG_CAN is not set
678# CONFIG_IRDA is not set
679CONFIG_BT=m
680CONFIG_BT_L2CAP=m
681CONFIG_BT_SCO=m
682CONFIG_BT_RFCOMM=m
683CONFIG_BT_RFCOMM_TTY=y
684CONFIG_BT_BNEP=m
685# CONFIG_BT_BNEP_MC_FILTER is not set
686# CONFIG_BT_BNEP_PROTO_FILTER is not set
687# CONFIG_BT_HIDP is not set
688
689#
690# Bluetooth device drivers
691#
692CONFIG_BT_HCIUSB=m
693CONFIG_BT_HCIUSB_SCO=y
694# CONFIG_BT_HCIBTUSB is not set
695CONFIG_BT_HCIBTSDIO=m
696CONFIG_BT_HCIUART=m
697CONFIG_BT_HCIUART_H4=y
698CONFIG_BT_HCIUART_BCSP=y
699CONFIG_BT_HCIUART_LL=y
700CONFIG_BT_HCIBCM203X=m
701CONFIG_BT_HCIBPA10X=m
702CONFIG_BT_HCIBFUSB=m
703CONFIG_BT_HCIVHCI=m
704# CONFIG_AF_RXRPC is not set
705CONFIG_FIB_RULES=y
706
707#
708# Wireless
709#
710CONFIG_CFG80211=m
711CONFIG_NL80211=y
712CONFIG_WIRELESS_EXT=y
713# CONFIG_WIRELESS_EXT_SYSFS is not set
714CONFIG_MAC80211=m
715
716#
717# Rate control algorithm selection
718#
719CONFIG_MAC80211_RC_PID=y
720CONFIG_MAC80211_RC_DEFAULT_PID=y
721CONFIG_MAC80211_RC_DEFAULT="pid"
722CONFIG_MAC80211_MESH=y
723CONFIG_MAC80211_LEDS=y
724CONFIG_MAC80211_DEBUGFS=y
725# CONFIG_MAC80211_DEBUG_MENU is not set
726CONFIG_IEEE80211=m
727# CONFIG_IEEE80211_DEBUG is not set
728CONFIG_IEEE80211_CRYPT_WEP=m
729CONFIG_IEEE80211_CRYPT_CCMP=m
730CONFIG_IEEE80211_CRYPT_TKIP=m
731CONFIG_RFKILL=m
732CONFIG_RFKILL_INPUT=m
733CONFIG_RFKILL_LEDS=y
734# CONFIG_NET_9P is not set
735
736#
737# Device Drivers
738#
739
740#
741# Generic Driver Options
742#
743CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
744CONFIG_STANDALONE=y
745CONFIG_PREVENT_FIRMWARE_BUILD=y
746CONFIG_FW_LOADER=y
747CONFIG_FIRMWARE_IN_KERNEL=y
748CONFIG_EXTRA_FIRMWARE=""
749# CONFIG_DEBUG_DRIVER is not set
750CONFIG_DEBUG_DEVRES=y
751# CONFIG_SYS_HYPERVISOR is not set
752CONFIG_CONNECTOR=y
753CONFIG_PROC_EVENTS=y
754# CONFIG_MTD is not set
755# CONFIG_PARPORT is not set
756CONFIG_PNP=y
757# CONFIG_PNP_DEBUG is not set
758
759#
760# Protocols
761#
762CONFIG_PNPACPI=y
763CONFIG_BLK_DEV=y
764# CONFIG_BLK_DEV_FD is not set
765# CONFIG_BLK_CPQ_DA is not set
766# CONFIG_BLK_CPQ_CISS_DA is not set
767# CONFIG_BLK_DEV_DAC960 is not set
768# CONFIG_BLK_DEV_UMEM is not set
769# CONFIG_BLK_DEV_COW_COMMON is not set
770CONFIG_BLK_DEV_LOOP=y
771CONFIG_BLK_DEV_CRYPTOLOOP=m
772# CONFIG_BLK_DEV_NBD is not set
773# CONFIG_BLK_DEV_SX8 is not set
774# CONFIG_BLK_DEV_UB is not set
775CONFIG_BLK_DEV_RAM=y
776CONFIG_BLK_DEV_RAM_COUNT=16
777CONFIG_BLK_DEV_RAM_SIZE=262144
778# CONFIG_BLK_DEV_XIP is not set
779CONFIG_CDROM_PKTCDVD=m
780CONFIG_CDROM_PKTCDVD_BUFFERS=8
781# CONFIG_CDROM_PKTCDVD_WCACHE is not set
782# CONFIG_ATA_OVER_ETH is not set
783# CONFIG_BLK_DEV_HD is not set
784CONFIG_MISC_DEVICES=y
785# CONFIG_IBM_ASM is not set
786# CONFIG_PHANTOM is not set
787CONFIG_EEPROM_93CX6=m
788# CONFIG_SGI_IOC4 is not set
789CONFIG_TIFM_CORE=m
790CONFIG_TIFM_7XX1=m
791# CONFIG_ACER_WMI is not set
792# CONFIG_FUJITSU_LAPTOP is not set
793# CONFIG_TC1100_WMI is not set
794# CONFIG_HP_WMI is not set
795# CONFIG_MSI_LAPTOP is not set
796# CONFIG_COMPAL_LAPTOP is not set
797# CONFIG_SONY_LAPTOP is not set
798# CONFIG_THINKPAD_ACPI is not set
799# CONFIG_INTEL_MENLOW is not set
800CONFIG_EEEPC_LAPTOP=y
801# CONFIG_ENCLOSURE_SERVICES is not set
802# CONFIG_HP_ILO is not set
803CONFIG_HAVE_IDE=y
804# CONFIG_IDE is not set
805
806#
807# SCSI device support
808#
809CONFIG_RAID_ATTRS=m
810CONFIG_SCSI=y
811CONFIG_SCSI_DMA=y
812# CONFIG_SCSI_TGT is not set
813# CONFIG_SCSI_NETLINK is not set
814CONFIG_SCSI_PROC_FS=y
815
816#
817# SCSI support type (disk, tape, CD-ROM)
818#
819CONFIG_BLK_DEV_SD=y
820CONFIG_CHR_DEV_ST=m
821# CONFIG_CHR_DEV_OSST is not set
822CONFIG_BLK_DEV_SR=y
823CONFIG_BLK_DEV_SR_VENDOR=y
824# CONFIG_CHR_DEV_SG is not set
825CONFIG_CHR_DEV_SCH=m
826
827#
828# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
829#
830CONFIG_SCSI_MULTI_LUN=y
831CONFIG_SCSI_CONSTANTS=y
832CONFIG_SCSI_LOGGING=y
833CONFIG_SCSI_SCAN_ASYNC=y
834CONFIG_SCSI_WAIT_SCAN=m
835
836#
837# SCSI Transports
838#
839# CONFIG_SCSI_SPI_ATTRS is not set
840# CONFIG_SCSI_FC_ATTRS is not set
841# CONFIG_SCSI_ISCSI_ATTRS is not set
842# CONFIG_SCSI_SAS_ATTRS is not set
843# CONFIG_SCSI_SAS_LIBSAS is not set
844# CONFIG_SCSI_SRP_ATTRS is not set
845CONFIG_SCSI_LOWLEVEL=y
846# CONFIG_ISCSI_TCP is not set
847# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
848# CONFIG_SCSI_3W_9XXX is not set
849# CONFIG_SCSI_ACARD is not set
850# CONFIG_SCSI_AACRAID is not set
851# CONFIG_SCSI_AIC7XXX is not set
852# CONFIG_SCSI_AIC7XXX_OLD is not set
853# CONFIG_SCSI_AIC79XX is not set
854# CONFIG_SCSI_AIC94XX is not set
855# CONFIG_SCSI_DPT_I2O is not set
856# CONFIG_SCSI_ADVANSYS is not set
857# CONFIG_SCSI_ARCMSR is not set
858# CONFIG_MEGARAID_NEWGEN is not set
859# CONFIG_MEGARAID_LEGACY is not set
860# CONFIG_MEGARAID_SAS is not set
861# CONFIG_SCSI_HPTIOP is not set
862# CONFIG_SCSI_BUSLOGIC is not set
863# CONFIG_SCSI_DMX3191D is not set
864# CONFIG_SCSI_EATA is not set
865# CONFIG_SCSI_FUTURE_DOMAIN is not set
866# CONFIG_SCSI_GDTH is not set
867# CONFIG_SCSI_IPS is not set
868# CONFIG_SCSI_INITIO is not set
869# CONFIG_SCSI_INIA100 is not set
870# CONFIG_SCSI_MVSAS is not set
871# CONFIG_SCSI_STEX is not set
872# CONFIG_SCSI_SYM53C8XX_2 is not set
873# CONFIG_SCSI_IPR is not set
874# CONFIG_SCSI_QLOGIC_1280 is not set
875# CONFIG_SCSI_QLA_FC is not set
876# CONFIG_SCSI_QLA_ISCSI is not set
877# CONFIG_SCSI_LPFC is not set
878# CONFIG_SCSI_DC395x is not set
879# CONFIG_SCSI_DC390T is not set
880# CONFIG_SCSI_NSP32 is not set
881# CONFIG_SCSI_DEBUG is not set
882# CONFIG_SCSI_SRP is not set
883# CONFIG_SCSI_DH is not set
884CONFIG_ATA=y
885# CONFIG_ATA_NONSTANDARD is not set
886CONFIG_ATA_ACPI=y
887# CONFIG_SATA_PMP is not set
888CONFIG_SATA_AHCI=y
889# CONFIG_SATA_SIL24 is not set
890CONFIG_ATA_SFF=y
891# CONFIG_SATA_SVW is not set
892CONFIG_ATA_PIIX=y
893# CONFIG_SATA_MV is not set
894# CONFIG_SATA_NV is not set
895# CONFIG_PDC_ADMA is not set
896# CONFIG_SATA_QSTOR is not set
897# CONFIG_SATA_PROMISE is not set
898# CONFIG_SATA_SX4 is not set
899# CONFIG_SATA_SIL is not set
900# CONFIG_SATA_SIS is not set
901# CONFIG_SATA_ULI is not set
902# CONFIG_SATA_VIA is not set
903# CONFIG_SATA_VITESSE is not set
904# CONFIG_SATA_INIC162X is not set
905# CONFIG_PATA_ACPI is not set
906# CONFIG_PATA_ALI is not set
907# CONFIG_PATA_AMD is not set
908# CONFIG_PATA_ARTOP is not set
909# CONFIG_PATA_ATIIXP is not set
910# CONFIG_PATA_CMD640_PCI is not set
911# CONFIG_PATA_CMD64X is not set
912# CONFIG_PATA_CS5520 is not set
913# CONFIG_PATA_CS5530 is not set
914# CONFIG_PATA_CS5535 is not set
915# CONFIG_PATA_CS5536 is not set
916# CONFIG_PATA_CYPRESS is not set
917# CONFIG_PATA_EFAR is not set
918# CONFIG_ATA_GENERIC is not set
919# CONFIG_PATA_HPT366 is not set
920# CONFIG_PATA_HPT37X is not set
921# CONFIG_PATA_HPT3X2N is not set
922# CONFIG_PATA_HPT3X3 is not set
923# CONFIG_PATA_IT821X is not set
924# CONFIG_PATA_IT8213 is not set
925# CONFIG_PATA_JMICRON is not set
926# CONFIG_PATA_TRIFLEX is not set
927# CONFIG_PATA_MARVELL is not set
928# CONFIG_PATA_MPIIX is not set
929# CONFIG_PATA_OLDPIIX is not set
930# CONFIG_PATA_NETCELL is not set
931# CONFIG_PATA_NINJA32 is not set
932# CONFIG_PATA_NS87410 is not set
933# CONFIG_PATA_NS87415 is not set
934# CONFIG_PATA_OPTI is not set
935# CONFIG_PATA_OPTIDMA is not set
936# CONFIG_PATA_PDC_OLD is not set
937# CONFIG_PATA_RADISYS is not set
938# CONFIG_PATA_RZ1000 is not set
939# CONFIG_PATA_SC1200 is not set
940# CONFIG_PATA_SERVERWORKS is not set
941# CONFIG_PATA_PDC2027X is not set
942# CONFIG_PATA_SIL680 is not set
943# CONFIG_PATA_SIS is not set
944# CONFIG_PATA_VIA is not set
945# CONFIG_PATA_WINBOND is not set
946CONFIG_PATA_SCH=y
947# CONFIG_MD is not set
948# CONFIG_FUSION is not set
949
950#
951# IEEE 1394 (FireWire) support
952#
953
954#
955# Enable only one of the two stacks, unless you know what you are doing
956#
957# CONFIG_FIREWIRE is not set
958# CONFIG_IEEE1394 is not set
959# CONFIG_I2O is not set
960# CONFIG_MACINTOSH_DRIVERS is not set
961CONFIG_NETDEVICES=y
962# CONFIG_DUMMY is not set
963# CONFIG_BONDING is not set
964CONFIG_MACVLAN=m
965# CONFIG_EQUALIZER is not set
966# CONFIG_TUN is not set
967# CONFIG_VETH is not set
968# CONFIG_NET_SB1000 is not set
969# CONFIG_ARCNET is not set
970CONFIG_PHYLIB=m
971
972#
973# MII PHY device drivers
974#
975CONFIG_MARVELL_PHY=m
976CONFIG_DAVICOM_PHY=m
977CONFIG_QSEMI_PHY=m
978CONFIG_LXT_PHY=m
979CONFIG_CICADA_PHY=m
980CONFIG_VITESSE_PHY=m
981CONFIG_SMSC_PHY=m
982CONFIG_BROADCOM_PHY=m
983CONFIG_ICPLUS_PHY=m
984CONFIG_REALTEK_PHY=m
985CONFIG_MDIO_BITBANG=m
986CONFIG_NET_ETHERNET=y
987CONFIG_MII=y
988CONFIG_HAPPYMEAL=m
989CONFIG_SUNGEM=m
990CONFIG_CASSINI=m
991CONFIG_NET_VENDOR_3COM=y
992# CONFIG_VORTEX is not set
993# CONFIG_TYPHOON is not set
994# CONFIG_NET_TULIP is not set
995# CONFIG_HP100 is not set
996# CONFIG_IBM_NEW_EMAC_ZMII is not set
997# CONFIG_IBM_NEW_EMAC_RGMII is not set
998# CONFIG_IBM_NEW_EMAC_TAH is not set
999# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
1000# CONFIG_NET_PCI is not set
1001# CONFIG_B44 is not set
1002CONFIG_NETDEV_1000=y
1003# CONFIG_ACENIC is not set
1004# CONFIG_DL2K is not set
1005# CONFIG_E1000 is not set
1006# CONFIG_E1000E is not set
1007# CONFIG_IP1000 is not set
1008# CONFIG_IGB is not set
1009# CONFIG_NS83820 is not set
1010# CONFIG_HAMACHI is not set
1011# CONFIG_YELLOWFIN is not set
1012# CONFIG_R8169 is not set
1013# CONFIG_SIS190 is not set
1014# CONFIG_SKGE is not set
1015# CONFIG_SKY2 is not set
1016# CONFIG_VIA_VELOCITY is not set
1017# CONFIG_TIGON3 is not set
1018# CONFIG_BNX2 is not set
1019# CONFIG_QLA3XXX is not set
1020CONFIG_ATL1=y
1021CONFIG_ATL1E=y
1022# CONFIG_NETDEV_10000 is not set
1023# CONFIG_TR is not set
1024
1025#
1026# Wireless LAN
1027#
1028CONFIG_WLAN_PRE80211=y
1029# CONFIG_STRIP is not set
1030CONFIG_WLAN_80211=y
1031# CONFIG_IPW2100 is not set
1032# CONFIG_IPW2200 is not set
1033# CONFIG_LIBERTAS is not set
1034# CONFIG_AIRO is not set
1035# CONFIG_HERMES is not set
1036# CONFIG_ATMEL is not set
1037# CONFIG_PRISM54 is not set
1038CONFIG_USB_ZD1201=m
1039CONFIG_USB_NET_RNDIS_WLAN=m
1040CONFIG_RTL8180=m
1041CONFIG_RTL8187=m
1042# CONFIG_ADM8211 is not set
1043# CONFIG_MAC80211_HWSIM is not set
1044# CONFIG_P54_COMMON is not set
1045CONFIG_ATH5K=m
1046# CONFIG_ATH5K_DEBUG is not set
1047# CONFIG_ATH9K is not set
1048CONFIG_IWLWIFI=m
1049CONFIG_IWLCORE=m
1050# CONFIG_IWLWIFI_LEDS is not set
1051CONFIG_IWLWIFI_RFKILL=y
1052# CONFIG_IWLWIFI_DEBUG is not set
1053# CONFIG_IWLAGN is not set
1054CONFIG_IWL3945=m
1055CONFIG_IWL3945_RFKILL=y
1056# CONFIG_IWL3945_SPECTRUM_MEASUREMENT is not set
1057# CONFIG_IWL3945_LEDS is not set
1058# CONFIG_IWL3945_DEBUG is not set
1059# CONFIG_HOSTAP is not set
1060# CONFIG_B43 is not set
1061# CONFIG_B43LEGACY is not set
1062# CONFIG_ZD1211RW is not set
1063CONFIG_RT2X00=m
1064CONFIG_RT2X00_LIB=m
1065CONFIG_RT2X00_LIB_PCI=m
1066CONFIG_RT2X00_LIB_USB=m
1067CONFIG_RT2X00_LIB_FIRMWARE=y
1068CONFIG_RT2X00_LIB_RFKILL=y
1069CONFIG_RT2X00_LIB_LEDS=y
1070CONFIG_RT2400PCI=m
1071CONFIG_RT2400PCI_RFKILL=y
1072CONFIG_RT2400PCI_LEDS=y
1073CONFIG_RT2500PCI=m
1074CONFIG_RT2500PCI_RFKILL=y
1075CONFIG_RT2500PCI_LEDS=y
1076CONFIG_RT61PCI=m
1077CONFIG_RT61PCI_RFKILL=y
1078CONFIG_RT61PCI_LEDS=y
1079CONFIG_RT2500USB=m
1080CONFIG_RT2500USB_LEDS=y
1081CONFIG_RT73USB=m
1082CONFIG_RT73USB_LEDS=y
1083CONFIG_RT2X00_LIB_DEBUGFS=y
1084# CONFIG_RT2X00_DEBUG is not set
1085
1086#
1087# USB Network Adapters
1088#
1089CONFIG_USB_CATC=m
1090CONFIG_USB_KAWETH=m
1091CONFIG_USB_PEGASUS=m
1092CONFIG_USB_RTL8150=m
1093CONFIG_USB_USBNET=m
1094CONFIG_USB_NET_AX8817X=m
1095CONFIG_USB_NET_CDCETHER=m
1096CONFIG_USB_NET_DM9601=m
1097CONFIG_USB_NET_GL620A=m
1098CONFIG_USB_NET_NET1080=m
1099CONFIG_USB_NET_PLUSB=m
1100CONFIG_USB_NET_MCS7830=m
1101CONFIG_USB_NET_RNDIS_HOST=m
1102CONFIG_USB_NET_CDC_SUBSET=m
1103CONFIG_USB_ALI_M5632=y
1104CONFIG_USB_AN2720=y
1105CONFIG_USB_BELKIN=y
1106CONFIG_USB_ARMLINUX=y
1107CONFIG_USB_EPSON2888=y
1108CONFIG_USB_KC2190=y
1109CONFIG_USB_NET_ZAURUS=m
1110# CONFIG_USB_HSO is not set
1111# CONFIG_WAN is not set
1112# CONFIG_FDDI is not set
1113# CONFIG_HIPPI is not set
1114CONFIG_PPP=m
1115CONFIG_PPP_MULTILINK=y
1116CONFIG_PPP_FILTER=y
1117CONFIG_PPP_ASYNC=m
1118CONFIG_PPP_SYNC_TTY=m
1119CONFIG_PPP_DEFLATE=m
1120# CONFIG_PPP_BSDCOMP is not set
1121CONFIG_PPP_MPPE=m
1122CONFIG_PPPOE=m
1123CONFIG_PPPOL2TP=m
1124# CONFIG_SLIP is not set
1125CONFIG_SLHC=m
1126CONFIG_NET_FC=y
1127CONFIG_NETCONSOLE=m
1128CONFIG_NETCONSOLE_DYNAMIC=y
1129CONFIG_NETPOLL=y
1130CONFIG_NETPOLL_TRAP=y
1131CONFIG_NET_POLL_CONTROLLER=y
1132# CONFIG_ISDN is not set
1133# CONFIG_PHONE is not set
1134
1135#
1136# Input device support
1137#
1138CONFIG_INPUT=y
1139CONFIG_INPUT_FF_MEMLESS=y
1140CONFIG_INPUT_POLLDEV=m
1141
1142#
1143# Userland interfaces
1144#
1145CONFIG_INPUT_MOUSEDEV=y
1146# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
1147CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
1148CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
1149CONFIG_INPUT_JOYDEV=m
1150CONFIG_INPUT_EVDEV=y
1151# CONFIG_INPUT_EVBUG is not set
1152
1153#
1154# Input Device Drivers
1155#
1156CONFIG_INPUT_KEYBOARD=y
1157CONFIG_KEYBOARD_ATKBD=y
1158# CONFIG_KEYBOARD_SUNKBD is not set
1159# CONFIG_KEYBOARD_LKKBD is not set
1160# CONFIG_KEYBOARD_XTKBD is not set
1161# CONFIG_KEYBOARD_NEWTON is not set
1162# CONFIG_KEYBOARD_STOWAWAY is not set
1163CONFIG_INPUT_MOUSE=y
1164CONFIG_MOUSE_PS2=y
1165CONFIG_MOUSE_PS2_ALPS=y
1166CONFIG_MOUSE_PS2_LOGIPS2PP=y
1167CONFIG_MOUSE_PS2_SYNAPTICS=y
1168CONFIG_MOUSE_PS2_LIFEBOOK=y
1169CONFIG_MOUSE_PS2_TRACKPOINT=y
1170# CONFIG_MOUSE_PS2_TOUCHKIT is not set
1171CONFIG_MOUSE_SERIAL=m
1172# CONFIG_MOUSE_APPLETOUCH is not set
1173# CONFIG_MOUSE_BCM5974 is not set
1174CONFIG_MOUSE_VSXXXAA=m
1175CONFIG_INPUT_JOYSTICK=y
1176# CONFIG_JOYSTICK_ANALOG is not set
1177# CONFIG_JOYSTICK_A3D is not set
1178# CONFIG_JOYSTICK_ADI is not set
1179# CONFIG_JOYSTICK_COBRA is not set
1180# CONFIG_JOYSTICK_GF2K is not set
1181# CONFIG_JOYSTICK_GRIP is not set
1182# CONFIG_JOYSTICK_GRIP_MP is not set
1183# CONFIG_JOYSTICK_GUILLEMOT is not set
1184# CONFIG_JOYSTICK_INTERACT is not set
1185# CONFIG_JOYSTICK_SIDEWINDER is not set
1186# CONFIG_JOYSTICK_TMDC is not set
1187# CONFIG_JOYSTICK_IFORCE is not set
1188# CONFIG_JOYSTICK_WARRIOR is not set
1189# CONFIG_JOYSTICK_MAGELLAN is not set
1190# CONFIG_JOYSTICK_SPACEORB is not set
1191# CONFIG_JOYSTICK_SPACEBALL is not set
1192# CONFIG_JOYSTICK_STINGER is not set
1193# CONFIG_JOYSTICK_TWIDJOY is not set
1194# CONFIG_JOYSTICK_ZHENHUA is not set
1195# CONFIG_JOYSTICK_JOYDUMP is not set
1196# CONFIG_JOYSTICK_XPAD is not set
1197# CONFIG_INPUT_TABLET is not set
1198CONFIG_INPUT_TOUCHSCREEN=y
1199CONFIG_TOUCHSCREEN_FUJITSU=m
1200CONFIG_TOUCHSCREEN_GUNZE=m
1201CONFIG_TOUCHSCREEN_ELO=m
1202CONFIG_TOUCHSCREEN_MTOUCH=m
1203CONFIG_TOUCHSCREEN_INEXIO=m
1204CONFIG_TOUCHSCREEN_MK712=m
1205CONFIG_TOUCHSCREEN_PENMOUNT=m
1206CONFIG_TOUCHSCREEN_TOUCHRIGHT=m
1207CONFIG_TOUCHSCREEN_TOUCHWIN=m
1208CONFIG_TOUCHSCREEN_UCB1400=m
1209# CONFIG_TOUCHSCREEN_WM97XX is not set
1210CONFIG_TOUCHSCREEN_USB_COMPOSITE=m
1211CONFIG_TOUCHSCREEN_USB_EGALAX=y
1212CONFIG_TOUCHSCREEN_USB_PANJIT=y
1213CONFIG_TOUCHSCREEN_USB_3M=y
1214CONFIG_TOUCHSCREEN_USB_ITM=y
1215CONFIG_TOUCHSCREEN_USB_ETURBO=y
1216CONFIG_TOUCHSCREEN_USB_GUNZE=y
1217CONFIG_TOUCHSCREEN_USB_DMC_TSC10=y
1218CONFIG_TOUCHSCREEN_USB_IRTOUCH=y
1219CONFIG_TOUCHSCREEN_USB_IDEALTEK=y
1220CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH=y
1221CONFIG_TOUCHSCREEN_USB_GOTOP=y
1222CONFIG_TOUCHSCREEN_TOUCHIT213=m
1223CONFIG_INPUT_MISC=y
1224# CONFIG_INPUT_PCSPKR is not set
1225# CONFIG_INPUT_APANEL is not set
1226# CONFIG_INPUT_WISTRON_BTNS is not set
1227CONFIG_INPUT_ATLAS_BTNS=m
1228CONFIG_INPUT_ATI_REMOTE=m
1229CONFIG_INPUT_ATI_REMOTE2=m
1230CONFIG_INPUT_KEYSPAN_REMOTE=m
1231CONFIG_INPUT_POWERMATE=m
1232CONFIG_INPUT_YEALINK=m
1233CONFIG_INPUT_UINPUT=m
1234
1235#
1236# Hardware I/O ports
1237#
1238CONFIG_SERIO=y
1239CONFIG_SERIO_I8042=y
1240CONFIG_SERIO_SERPORT=y
1241# CONFIG_SERIO_CT82C710 is not set
1242# CONFIG_SERIO_PCIPS2 is not set
1243CONFIG_SERIO_LIBPS2=y
1244CONFIG_SERIO_RAW=m
1245# CONFIG_GAMEPORT is not set
1246
1247#
1248# Character devices
1249#
1250CONFIG_VT=y
1251CONFIG_CONSOLE_TRANSLATIONS=y
1252CONFIG_VT_CONSOLE=y
1253CONFIG_HW_CONSOLE=y
1254CONFIG_VT_HW_CONSOLE_BINDING=y
1255# CONFIG_DEVKMEM is not set
1256# CONFIG_SERIAL_NONSTANDARD is not set
1257# CONFIG_NOZOMI is not set
1258
1259#
1260# Serial drivers
1261#
1262# CONFIG_SERIAL_8250 is not set
1263CONFIG_FIX_EARLYCON_MEM=y
1264
1265#
1266# Non-8250 serial port support
1267#
1268# CONFIG_SERIAL_JSM is not set
1269CONFIG_UNIX98_PTYS=y
1270# CONFIG_LEGACY_PTYS is not set
1271# CONFIG_IPMI_HANDLER is not set
1272# CONFIG_HW_RANDOM is not set
1273# CONFIG_NVRAM is not set
1274# CONFIG_R3964 is not set
1275# CONFIG_APPLICOM is not set
1276# CONFIG_SONYPI is not set
1277# CONFIG_MWAVE is not set
1278# CONFIG_PC8736x_GPIO is not set
1279# CONFIG_NSC_GPIO is not set
1280# CONFIG_CS5535_GPIO is not set
1281# CONFIG_RAW_DRIVER is not set
1282CONFIG_HPET=y
1283# CONFIG_HPET_MMAP is not set
1284# CONFIG_HANGCHECK_TIMER is not set
1285# CONFIG_TCG_TPM is not set
1286# CONFIG_TELCLOCK is not set
1287CONFIG_DEVPORT=y
1288CONFIG_I2C=y
1289CONFIG_I2C_BOARDINFO=y
1290# CONFIG_I2C_CHARDEV is not set
1291CONFIG_I2C_HELPER_AUTO=y
1292CONFIG_I2C_ALGOBIT=y
1293
1294#
1295# I2C Hardware Bus support
1296#
1297
1298#
1299# PC SMBus host controller drivers
1300#
1301# CONFIG_I2C_ALI1535 is not set
1302# CONFIG_I2C_ALI1563 is not set
1303# CONFIG_I2C_ALI15X3 is not set
1304# CONFIG_I2C_AMD756 is not set
1305# CONFIG_I2C_AMD8111 is not set
1306# CONFIG_I2C_I801 is not set
1307# CONFIG_I2C_ISCH is not set
1308# CONFIG_I2C_PIIX4 is not set
1309# CONFIG_I2C_NFORCE2 is not set
1310# CONFIG_I2C_SIS5595 is not set
1311# CONFIG_I2C_SIS630 is not set
1312# CONFIG_I2C_SIS96X is not set
1313# CONFIG_I2C_VIA is not set
1314# CONFIG_I2C_VIAPRO is not set
1315
1316#
1317# I2C system bus drivers (mostly embedded / system-on-chip)
1318#
1319# CONFIG_I2C_OCORES is not set
1320# CONFIG_I2C_SIMTEC is not set
1321
1322#
1323# External I2C/SMBus adapter drivers
1324#
1325# CONFIG_I2C_PARPORT_LIGHT is not set
1326# CONFIG_I2C_TAOS_EVM is not set
1327# CONFIG_I2C_TINY_USB is not set
1328
1329#
1330# Graphics adapter I2C/DDC channel drivers
1331#
1332# CONFIG_I2C_VOODOO3 is not set
1333
1334#
1335# Other I2C/SMBus bus drivers
1336#
1337# CONFIG_I2C_PCA_PLATFORM is not set
1338# CONFIG_I2C_STUB is not set
1339# CONFIG_SCx200_ACB is not set
1340
1341#
1342# Miscellaneous I2C Chip support
1343#
1344# CONFIG_DS1682 is not set
1345# CONFIG_AT24 is not set
1346# CONFIG_SENSORS_EEPROM is not set
1347# CONFIG_SENSORS_PCF8574 is not set
1348# CONFIG_PCF8575 is not set
1349# CONFIG_SENSORS_PCA9539 is not set
1350# CONFIG_SENSORS_PCF8591 is not set
1351# CONFIG_SENSORS_MAX6875 is not set
1352# CONFIG_SENSORS_TSL2550 is not set
1353# CONFIG_I2C_DEBUG_CORE is not set
1354# CONFIG_I2C_DEBUG_ALGO is not set
1355# CONFIG_I2C_DEBUG_BUS is not set
1356# CONFIG_I2C_DEBUG_CHIP is not set
1357# CONFIG_SPI is not set
1358CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
1359# CONFIG_GPIOLIB is not set
1360# CONFIG_W1 is not set
1361CONFIG_POWER_SUPPLY=y
1362# CONFIG_POWER_SUPPLY_DEBUG is not set
1363# CONFIG_PDA_POWER is not set
1364# CONFIG_BATTERY_DS2760 is not set
1365CONFIG_HWMON=y
1366# CONFIG_HWMON_VID is not set
1367# CONFIG_SENSORS_ABITUGURU is not set
1368# CONFIG_SENSORS_ABITUGURU3 is not set
1369# CONFIG_SENSORS_AD7414 is not set
1370# CONFIG_SENSORS_AD7418 is not set
1371# CONFIG_SENSORS_ADM1021 is not set
1372# CONFIG_SENSORS_ADM1025 is not set
1373# CONFIG_SENSORS_ADM1026 is not set
1374# CONFIG_SENSORS_ADM1029 is not set
1375# CONFIG_SENSORS_ADM1031 is not set
1376# CONFIG_SENSORS_ADM9240 is not set
1377# CONFIG_SENSORS_ADT7470 is not set
1378# CONFIG_SENSORS_ADT7473 is not set
1379# CONFIG_SENSORS_K8TEMP is not set
1380# CONFIG_SENSORS_ASB100 is not set
1381# CONFIG_SENSORS_ATXP1 is not set
1382# CONFIG_SENSORS_DS1621 is not set
1383# CONFIG_SENSORS_I5K_AMB is not set
1384# CONFIG_SENSORS_F71805F is not set
1385# CONFIG_SENSORS_F71882FG is not set
1386# CONFIG_SENSORS_F75375S is not set
1387# CONFIG_SENSORS_FSCHER is not set
1388# CONFIG_SENSORS_FSCPOS is not set
1389# CONFIG_SENSORS_FSCHMD is not set
1390# CONFIG_SENSORS_GL518SM is not set
1391# CONFIG_SENSORS_GL520SM is not set
1392# CONFIG_SENSORS_CORETEMP is not set
1393# CONFIG_SENSORS_IT87 is not set
1394# CONFIG_SENSORS_LM63 is not set
1395# CONFIG_SENSORS_LM75 is not set
1396# CONFIG_SENSORS_LM77 is not set
1397# CONFIG_SENSORS_LM78 is not set
1398# CONFIG_SENSORS_LM80 is not set
1399# CONFIG_SENSORS_LM83 is not set
1400# CONFIG_SENSORS_LM85 is not set
1401# CONFIG_SENSORS_LM87 is not set
1402# CONFIG_SENSORS_LM90 is not set
1403# CONFIG_SENSORS_LM92 is not set
1404# CONFIG_SENSORS_LM93 is not set
1405# CONFIG_SENSORS_MAX1619 is not set
1406# CONFIG_SENSORS_MAX6650 is not set
1407# CONFIG_SENSORS_PC87360 is not set
1408# CONFIG_SENSORS_PC87427 is not set
1409# CONFIG_SENSORS_SIS5595 is not set
1410# CONFIG_SENSORS_DME1737 is not set
1411# CONFIG_SENSORS_SMSC47M1 is not set
1412# CONFIG_SENSORS_SMSC47M192 is not set
1413# CONFIG_SENSORS_SMSC47B397 is not set
1414# CONFIG_SENSORS_ADS7828 is not set
1415# CONFIG_SENSORS_THMC50 is not set
1416# CONFIG_SENSORS_VIA686A is not set
1417# CONFIG_SENSORS_VT1211 is not set
1418# CONFIG_SENSORS_VT8231 is not set
1419# CONFIG_SENSORS_W83781D is not set
1420# CONFIG_SENSORS_W83791D is not set
1421# CONFIG_SENSORS_W83792D is not set
1422# CONFIG_SENSORS_W83793 is not set
1423# CONFIG_SENSORS_W83L785TS is not set
1424# CONFIG_SENSORS_W83L786NG is not set
1425# CONFIG_SENSORS_W83627HF is not set
1426# CONFIG_SENSORS_W83627EHF is not set
1427# CONFIG_SENSORS_HDAPS is not set
1428# CONFIG_SENSORS_APPLESMC is not set
1429# CONFIG_HWMON_DEBUG_CHIP is not set
1430CONFIG_THERMAL=y
1431# CONFIG_THERMAL_HWMON is not set
1432# CONFIG_WATCHDOG is not set
1433
1434#
1435# Sonics Silicon Backplane
1436#
1437CONFIG_SSB_POSSIBLE=y
1438# CONFIG_SSB is not set
1439
1440#
1441# Multifunction device drivers
1442#
1443# CONFIG_MFD_CORE is not set
1444# CONFIG_MFD_SM501 is not set
1445# CONFIG_HTC_PASIC3 is not set
1446# CONFIG_MFD_TMIO is not set
1447
1448#
1449# Multimedia devices
1450#
1451
1452#
1453# Multimedia core support
1454#
1455CONFIG_VIDEO_DEV=y
1456CONFIG_VIDEO_V4L2_COMMON=y
1457# CONFIG_VIDEO_ALLOW_V4L1 is not set
1458CONFIG_VIDEO_V4L1_COMPAT=y
1459CONFIG_DVB_CORE=y
1460CONFIG_VIDEO_MEDIA=y
1461
1462#
1463# Multimedia drivers
1464#
1465# CONFIG_MEDIA_ATTACH is not set
1466CONFIG_MEDIA_TUNER=y
1467# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set
1468CONFIG_MEDIA_TUNER_SIMPLE=y
1469CONFIG_MEDIA_TUNER_TDA8290=y
1470CONFIG_MEDIA_TUNER_TDA9887=y
1471CONFIG_MEDIA_TUNER_TEA5761=y
1472CONFIG_MEDIA_TUNER_TEA5767=y
1473CONFIG_MEDIA_TUNER_MT20XX=y
1474CONFIG_MEDIA_TUNER_XC2028=y
1475CONFIG_MEDIA_TUNER_XC5000=y
1476CONFIG_VIDEO_V4L2=y
1477CONFIG_VIDEO_CAPTURE_DRIVERS=y
1478# CONFIG_VIDEO_ADV_DEBUG is not set
1479CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
1480# CONFIG_VIDEO_VIVI is not set
1481# CONFIG_VIDEO_BT848 is not set
1482# CONFIG_VIDEO_SAA5246A is not set
1483# CONFIG_VIDEO_SAA5249 is not set
1484# CONFIG_VIDEO_SAA7134 is not set
1485# CONFIG_VIDEO_HEXIUM_ORION is not set
1486# CONFIG_VIDEO_HEXIUM_GEMINI is not set
1487# CONFIG_VIDEO_CX88 is not set
1488# CONFIG_VIDEO_CX23885 is not set
1489# CONFIG_VIDEO_AU0828 is not set
1490# CONFIG_VIDEO_CX18 is not set
1491# CONFIG_VIDEO_CAFE_CCIC is not set
1492CONFIG_V4L_USB_DRIVERS=y
1493CONFIG_USB_VIDEO_CLASS=y
1494CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y
1495# CONFIG_USB_GSPCA is not set
1496# CONFIG_VIDEO_PVRUSB2 is not set
1497# CONFIG_VIDEO_EM28XX is not set
1498# CONFIG_VIDEO_USBVISION is not set
1499# CONFIG_USB_ET61X251 is not set
1500# CONFIG_USB_SN9C102 is not set
1501# CONFIG_USB_ZC0301 is not set
1502# CONFIG_USB_ZR364XX is not set
1503# CONFIG_USB_STKWEBCAM is not set
1504# CONFIG_USB_S2255 is not set
1505# CONFIG_SOC_CAMERA is not set
1506# CONFIG_VIDEO_SH_MOBILE_CEU is not set
1507# CONFIG_RADIO_ADAPTERS is not set
1508# CONFIG_DVB_CAPTURE_DRIVERS is not set
1509# CONFIG_DAB is not set
1510
1511#
1512# Graphics support
1513#
1514CONFIG_AGP=y
1515# CONFIG_AGP_ALI is not set
1516# CONFIG_AGP_ATI is not set
1517# CONFIG_AGP_AMD is not set
1518CONFIG_AGP_AMD64=y
1519CONFIG_AGP_INTEL=y
1520# CONFIG_AGP_NVIDIA is not set
1521# CONFIG_AGP_SIS is not set
1522# CONFIG_AGP_SWORKS is not set
1523# CONFIG_AGP_VIA is not set
1524# CONFIG_AGP_EFFICEON is not set
1525CONFIG_DRM=y
1526# CONFIG_DRM_TDFX is not set
1527# CONFIG_DRM_R128 is not set
1528# CONFIG_DRM_RADEON is not set
1529CONFIG_DRM_I810=y
1530# CONFIG_DRM_I830 is not set
1531CONFIG_DRM_I915=y
1532# CONFIG_DRM_MGA is not set
1533# CONFIG_DRM_SIS is not set
1534# CONFIG_DRM_VIA is not set
1535# CONFIG_DRM_SAVAGE is not set
1536# CONFIG_VGASTATE is not set
1537CONFIG_VIDEO_OUTPUT_CONTROL=y
1538CONFIG_FB=y
1539CONFIG_FIRMWARE_EDID=y
1540CONFIG_FB_DDC=y
1541CONFIG_FB_CFB_FILLRECT=y
1542CONFIG_FB_CFB_COPYAREA=y
1543CONFIG_FB_CFB_IMAGEBLIT=y
1544# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
1545# CONFIG_FB_SYS_FILLRECT is not set
1546# CONFIG_FB_SYS_COPYAREA is not set
1547# CONFIG_FB_SYS_IMAGEBLIT is not set
1548# CONFIG_FB_FOREIGN_ENDIAN is not set
1549# CONFIG_FB_SYS_FOPS is not set
1550# CONFIG_FB_SVGALIB is not set
1551# CONFIG_FB_MACMODES is not set
1552# CONFIG_FB_BACKLIGHT is not set
1553CONFIG_FB_MODE_HELPERS=y
1554# CONFIG_FB_TILEBLITTING is not set
1555
1556#
1557# Frame buffer hardware drivers
1558#
1559# CONFIG_FB_CIRRUS is not set
1560# CONFIG_FB_PM2 is not set
1561# CONFIG_FB_CYBER2000 is not set
1562# CONFIG_FB_ARC is not set
1563# CONFIG_FB_ASILIANT is not set
1564# CONFIG_FB_IMSTT is not set
1565# CONFIG_FB_VGA16 is not set
1566# CONFIG_FB_UVESA is not set
1567# CONFIG_FB_VESA is not set
1568# CONFIG_FB_EFI is not set
1569# CONFIG_FB_N411 is not set
1570# CONFIG_FB_HGA is not set
1571# CONFIG_FB_S1D13XXX is not set
1572# CONFIG_FB_NVIDIA is not set
1573# CONFIG_FB_RIVA is not set
1574# CONFIG_FB_I810 is not set
1575# CONFIG_FB_LE80578 is not set
1576CONFIG_FB_INTEL=y
1577CONFIG_FB_INTEL_DEBUG=y
1578CONFIG_FB_INTEL_I2C=y
1579# CONFIG_FB_MATROX is not set
1580# CONFIG_FB_RADEON is not set
1581# CONFIG_FB_ATY128 is not set
1582# CONFIG_FB_ATY is not set
1583# CONFIG_FB_S3 is not set
1584# CONFIG_FB_SAVAGE is not set
1585# CONFIG_FB_SIS is not set
1586# CONFIG_FB_NEOMAGIC is not set
1587# CONFIG_FB_KYRO is not set
1588# CONFIG_FB_3DFX is not set
1589# CONFIG_FB_VOODOO1 is not set
1590# CONFIG_FB_VT8623 is not set
1591# CONFIG_FB_CYBLA is not set
1592# CONFIG_FB_TRIDENT is not set
1593# CONFIG_FB_ARK is not set
1594# CONFIG_FB_PM3 is not set
1595# CONFIG_FB_CARMINE is not set
1596# CONFIG_FB_GEODE is not set
1597# CONFIG_FB_VIRTUAL is not set
1598CONFIG_BACKLIGHT_LCD_SUPPORT=y
1599CONFIG_LCD_CLASS_DEVICE=y
1600# CONFIG_LCD_ILI9320 is not set
1601CONFIG_LCD_PLATFORM=y
1602CONFIG_BACKLIGHT_CLASS_DEVICE=y
1603# CONFIG_BACKLIGHT_CORGI is not set
1604# CONFIG_BACKLIGHT_PROGEAR is not set
1605CONFIG_BACKLIGHT_MBP_NVIDIA=y
1606
1607#
1608# Display device support
1609#
1610CONFIG_DISPLAY_SUPPORT=y
1611
1612#
1613# Display hardware drivers
1614#
1615
1616#
1617# Console display driver support
1618#
1619CONFIG_VGA_CONSOLE=y
1620CONFIG_VGACON_SOFT_SCROLLBACK=y
1621CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=64
1622CONFIG_VIDEO_SELECT=y
1623CONFIG_DUMMY_CONSOLE=y
1624CONFIG_FRAMEBUFFER_CONSOLE=y
1625# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
1626# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
1627# CONFIG_FONTS is not set
1628CONFIG_FONT_8x8=y
1629CONFIG_FONT_8x16=y
1630# CONFIG_LOGO is not set
1631CONFIG_SOUND=y
1632CONFIG_SND=y
1633CONFIG_SND_TIMER=y
1634CONFIG_SND_PCM=y
1635CONFIG_SND_HWDEP=y
1636CONFIG_SND_RAWMIDI=m
1637CONFIG_SND_SEQUENCER=y
1638CONFIG_SND_SEQ_DUMMY=y
1639# CONFIG_SND_MIXER_OSS is not set
1640# CONFIG_SND_PCM_OSS is not set
1641# CONFIG_SND_SEQUENCER_OSS is not set
1642CONFIG_SND_DYNAMIC_MINORS=y
1643# CONFIG_SND_SUPPORT_OLD_API is not set
1644CONFIG_SND_VERBOSE_PROCFS=y
1645CONFIG_SND_VERBOSE_PRINTK=y
1646CONFIG_SND_DEBUG=y
1647# CONFIG_SND_DEBUG_VERBOSE is not set
1648CONFIG_SND_PCM_XRUN_DEBUG=y
1649CONFIG_SND_VMASTER=y
1650CONFIG_SND_AC97_CODEC=y
1651CONFIG_SND_DRIVERS=y
1652# CONFIG_SND_PCSP is not set
1653# CONFIG_SND_DUMMY is not set
1654# CONFIG_SND_VIRMIDI is not set
1655# CONFIG_SND_MTPAV is not set
1656# CONFIG_SND_SERIAL_U16550 is not set
1657# CONFIG_SND_MPU401 is not set
1658CONFIG_SND_AC97_POWER_SAVE=y
1659CONFIG_SND_AC97_POWER_SAVE_DEFAULT=5
1660CONFIG_SND_PCI=y
1661# CONFIG_SND_AD1889 is not set
1662# CONFIG_SND_ALS300 is not set
1663# CONFIG_SND_ALS4000 is not set
1664# CONFIG_SND_ALI5451 is not set
1665# CONFIG_SND_ATIIXP is not set
1666# CONFIG_SND_ATIIXP_MODEM is not set
1667# CONFIG_SND_AU8810 is not set
1668# CONFIG_SND_AU8820 is not set
1669# CONFIG_SND_AU8830 is not set
1670# CONFIG_SND_AW2 is not set
1671# CONFIG_SND_AZT3328 is not set
1672# CONFIG_SND_BT87X is not set
1673# CONFIG_SND_CA0106 is not set
1674# CONFIG_SND_CMIPCI is not set
1675# CONFIG_SND_OXYGEN is not set
1676# CONFIG_SND_CS4281 is not set
1677# CONFIG_SND_CS46XX is not set
1678# CONFIG_SND_CS5530 is not set
1679# CONFIG_SND_CS5535AUDIO is not set
1680# CONFIG_SND_DARLA20 is not set
1681# CONFIG_SND_GINA20 is not set
1682# CONFIG_SND_LAYLA20 is not set
1683# CONFIG_SND_DARLA24 is not set
1684# CONFIG_SND_GINA24 is not set
1685# CONFIG_SND_LAYLA24 is not set
1686# CONFIG_SND_MONA is not set
1687# CONFIG_SND_MIA is not set
1688# CONFIG_SND_ECHO3G is not set
1689# CONFIG_SND_INDIGO is not set
1690# CONFIG_SND_INDIGOIO is not set
1691# CONFIG_SND_INDIGODJ is not set
1692# CONFIG_SND_EMU10K1 is not set
1693# CONFIG_SND_EMU10K1X is not set
1694# CONFIG_SND_ENS1370 is not set
1695# CONFIG_SND_ENS1371 is not set
1696# CONFIG_SND_ES1938 is not set
1697# CONFIG_SND_ES1968 is not set
1698# CONFIG_SND_FM801 is not set
1699CONFIG_SND_HDA_INTEL=y
1700CONFIG_SND_HDA_HWDEP=y
1701CONFIG_SND_HDA_CODEC_REALTEK=y
1702CONFIG_SND_HDA_CODEC_ANALOG=y
1703CONFIG_SND_HDA_CODEC_SIGMATEL=y
1704CONFIG_SND_HDA_CODEC_VIA=y
1705CONFIG_SND_HDA_CODEC_ATIHDMI=y
1706CONFIG_SND_HDA_CODEC_CONEXANT=y
1707CONFIG_SND_HDA_CODEC_CMEDIA=y
1708CONFIG_SND_HDA_CODEC_SI3054=y
1709CONFIG_SND_HDA_GENERIC=y
1710CONFIG_SND_HDA_POWER_SAVE=y
1711CONFIG_SND_HDA_POWER_SAVE_DEFAULT=0
1712# CONFIG_SND_HDSP is not set
1713# CONFIG_SND_HDSPM is not set
1714# CONFIG_SND_HIFIER is not set
1715# CONFIG_SND_ICE1712 is not set
1716# CONFIG_SND_ICE1724 is not set
1717CONFIG_SND_INTEL8X0=y
1718# CONFIG_SND_INTEL8X0M is not set
1719# CONFIG_SND_KORG1212 is not set
1720# CONFIG_SND_MAESTRO3 is not set
1721# CONFIG_SND_MIXART is not set
1722# CONFIG_SND_NM256 is not set
1723# CONFIG_SND_PCXHR is not set
1724# CONFIG_SND_RIPTIDE is not set
1725# CONFIG_SND_RME32 is not set
1726# CONFIG_SND_RME96 is not set
1727# CONFIG_SND_RME9652 is not set
1728# CONFIG_SND_SIS7019 is not set
1729# CONFIG_SND_SONICVIBES is not set
1730# CONFIG_SND_TRIDENT is not set
1731# CONFIG_SND_VIA82XX is not set
1732# CONFIG_SND_VIA82XX_MODEM is not set
1733# CONFIG_SND_VIRTUOSO is not set
1734# CONFIG_SND_VX222 is not set
1735# CONFIG_SND_YMFPCI is not set
1736CONFIG_SND_USB=y
1737CONFIG_SND_USB_AUDIO=m
1738CONFIG_SND_USB_USX2Y=m
1739CONFIG_SND_USB_CAIAQ=m
1740CONFIG_SND_USB_CAIAQ_INPUT=y
1741# CONFIG_SND_SOC is not set
1742# CONFIG_SOUND_PRIME is not set
1743CONFIG_AC97_BUS=y
1744CONFIG_HID_SUPPORT=y
1745CONFIG_HID=y
1746CONFIG_HID_DEBUG=y
1747CONFIG_HIDRAW=y
1748
1749#
1750# USB Input Devices
1751#
1752CONFIG_USB_HID=y
1753CONFIG_USB_HIDINPUT_POWERBOOK=y
1754CONFIG_HID_FF=y
1755CONFIG_HID_PID=y
1756CONFIG_LOGITECH_FF=y
1757# CONFIG_LOGIRUMBLEPAD2_FF is not set
1758CONFIG_PANTHERLORD_FF=y
1759CONFIG_THRUSTMASTER_FF=y
1760CONFIG_ZEROPLUS_FF=y
1761CONFIG_USB_HIDDEV=y
1762CONFIG_USB_SUPPORT=y
1763CONFIG_USB_ARCH_HAS_HCD=y
1764CONFIG_USB_ARCH_HAS_OHCI=y
1765CONFIG_USB_ARCH_HAS_EHCI=y
1766CONFIG_USB=y
1767# CONFIG_USB_DEBUG is not set
1768CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
1769
1770#
1771# Miscellaneous USB options
1772#
1773CONFIG_USB_DEVICEFS=y
1774# CONFIG_USB_DEVICE_CLASS is not set
1775# CONFIG_USB_DYNAMIC_MINORS is not set
1776CONFIG_USB_SUSPEND=y
1777# CONFIG_USB_OTG is not set
1778CONFIG_USB_MON=y
1779
1780#
1781# USB Host Controller Drivers
1782#
1783# CONFIG_USB_C67X00_HCD is not set
1784CONFIG_USB_EHCI_HCD=y
1785CONFIG_USB_EHCI_ROOT_HUB_TT=y
1786CONFIG_USB_EHCI_TT_NEWSCHED=y
1787CONFIG_USB_ISP116X_HCD=m
1788# CONFIG_USB_ISP1760_HCD is not set
1789CONFIG_USB_OHCI_HCD=y
1790# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
1791# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
1792CONFIG_USB_OHCI_LITTLE_ENDIAN=y
1793CONFIG_USB_UHCI_HCD=y
1794CONFIG_USB_U132_HCD=m
1795CONFIG_USB_SL811_HCD=m
1796# CONFIG_USB_R8A66597_HCD is not set
1797
1798#
1799# USB Device Class drivers
1800#
1801CONFIG_USB_ACM=m
1802CONFIG_USB_PRINTER=m
1803# CONFIG_USB_WDM is not set
1804
1805#
1806# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
1807#
1808
1809#
1810# may also be needed; see USB_STORAGE Help for more information
1811#
1812CONFIG_USB_STORAGE=y
1813# CONFIG_USB_STORAGE_DEBUG is not set
1814CONFIG_USB_STORAGE_DATAFAB=y
1815CONFIG_USB_STORAGE_FREECOM=y
1816CONFIG_USB_STORAGE_ISD200=y
1817CONFIG_USB_STORAGE_DPCM=y
1818CONFIG_USB_STORAGE_USBAT=y
1819CONFIG_USB_STORAGE_SDDR09=y
1820CONFIG_USB_STORAGE_SDDR55=y
1821CONFIG_USB_STORAGE_JUMPSHOT=y
1822CONFIG_USB_STORAGE_ALAUDA=y
1823# CONFIG_USB_STORAGE_ONETOUCH is not set
1824CONFIG_USB_STORAGE_KARMA=y
1825# CONFIG_USB_STORAGE_SIERRA is not set
1826# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
1827# CONFIG_USB_LIBUSUAL is not set
1828
1829#
1830# USB Imaging devices
1831#
1832CONFIG_USB_MDC800=m
1833CONFIG_USB_MICROTEK=m
1834
1835#
1836# USB port drivers
1837#
1838CONFIG_USB_SERIAL=m
1839CONFIG_USB_EZUSB=y
1840CONFIG_USB_SERIAL_GENERIC=y
1841CONFIG_USB_SERIAL_AIRCABLE=m
1842CONFIG_USB_SERIAL_ARK3116=m
1843CONFIG_USB_SERIAL_BELKIN=m
1844CONFIG_USB_SERIAL_CH341=m
1845CONFIG_USB_SERIAL_WHITEHEAT=m
1846CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
1847CONFIG_USB_SERIAL_CP2101=m
1848CONFIG_USB_SERIAL_CYPRESS_M8=m
1849CONFIG_USB_SERIAL_EMPEG=m
1850CONFIG_USB_SERIAL_FTDI_SIO=m
1851CONFIG_USB_SERIAL_FUNSOFT=m
1852CONFIG_USB_SERIAL_VISOR=m
1853CONFIG_USB_SERIAL_IPAQ=m
1854CONFIG_USB_SERIAL_IR=m
1855CONFIG_USB_SERIAL_EDGEPORT=m
1856CONFIG_USB_SERIAL_EDGEPORT_TI=m
1857CONFIG_USB_SERIAL_GARMIN=m
1858CONFIG_USB_SERIAL_IPW=m
1859CONFIG_USB_SERIAL_IUU=m
1860CONFIG_USB_SERIAL_KEYSPAN_PDA=m
1861CONFIG_USB_SERIAL_KEYSPAN=m
1862CONFIG_USB_SERIAL_KEYSPAN_MPR=y
1863CONFIG_USB_SERIAL_KEYSPAN_USA28=y
1864CONFIG_USB_SERIAL_KEYSPAN_USA28X=y
1865CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y
1866CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y
1867CONFIG_USB_SERIAL_KEYSPAN_USA19=y
1868CONFIG_USB_SERIAL_KEYSPAN_USA18X=y
1869CONFIG_USB_SERIAL_KEYSPAN_USA19W=y
1870CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y
1871CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y
1872CONFIG_USB_SERIAL_KEYSPAN_USA49W=y
1873CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
1874CONFIG_USB_SERIAL_KLSI=m
1875CONFIG_USB_SERIAL_KOBIL_SCT=m
1876CONFIG_USB_SERIAL_MCT_U232=m
1877CONFIG_USB_SERIAL_MOS7720=m
1878CONFIG_USB_SERIAL_MOS7840=m
1879# CONFIG_USB_SERIAL_MOTOROLA is not set
1880CONFIG_USB_SERIAL_NAVMAN=m
1881CONFIG_USB_SERIAL_PL2303=m
1882CONFIG_USB_SERIAL_OTI6858=m
1883# CONFIG_USB_SERIAL_SPCP8X5 is not set
1884CONFIG_USB_SERIAL_HP4X=m
1885CONFIG_USB_SERIAL_SAFE=m
1886CONFIG_USB_SERIAL_SAFE_PADDED=y
1887CONFIG_USB_SERIAL_SIERRAWIRELESS=m
1888CONFIG_USB_SERIAL_TI=m
1889CONFIG_USB_SERIAL_CYBERJACK=m
1890CONFIG_USB_SERIAL_XIRCOM=m
1891CONFIG_USB_SERIAL_OPTION=m
1892CONFIG_USB_SERIAL_OMNINET=m
1893CONFIG_USB_SERIAL_DEBUG=m
1894
1895#
1896# USB Miscellaneous drivers
1897#
1898CONFIG_USB_EMI62=m
1899CONFIG_USB_EMI26=m
1900CONFIG_USB_ADUTUX=m
1901# CONFIG_USB_RIO500 is not set
1902CONFIG_USB_LEGOTOWER=m
1903CONFIG_USB_LCD=m
1904CONFIG_USB_BERRY_CHARGE=m
1905CONFIG_USB_LED=m
1906# CONFIG_USB_CYPRESS_CY7C63 is not set
1907# CONFIG_USB_CYTHERM is not set
1908CONFIG_USB_PHIDGET=m
1909CONFIG_USB_PHIDGETKIT=m
1910CONFIG_USB_PHIDGETMOTORCONTROL=m
1911CONFIG_USB_PHIDGETSERVO=m
1912CONFIG_USB_IDMOUSE=m
1913CONFIG_USB_FTDI_ELAN=m
1914CONFIG_USB_APPLEDISPLAY=m
1915CONFIG_USB_SISUSBVGA=m
1916CONFIG_USB_SISUSBVGA_CON=y
1917CONFIG_USB_LD=m
1918CONFIG_USB_TRANCEVIBRATOR=m
1919CONFIG_USB_IOWARRIOR=m
1920# CONFIG_USB_TEST is not set
1921# CONFIG_USB_ISIGHTFW is not set
1922# CONFIG_USB_GADGET is not set
1923CONFIG_MMC=m
1924# CONFIG_MMC_DEBUG is not set
1925# CONFIG_MMC_UNSAFE_RESUME is not set
1926
1927#
1928# MMC/SD Card Drivers
1929#
1930CONFIG_MMC_BLOCK=m
1931CONFIG_MMC_BLOCK_BOUNCE=y
1932CONFIG_SDIO_UART=m
1933# CONFIG_MMC_TEST is not set
1934
1935#
1936# MMC/SD Host Controller Drivers
1937#
1938CONFIG_MMC_SDHCI=m
1939# CONFIG_MMC_SDHCI_PCI is not set
1940CONFIG_MMC_WBSD=m
1941CONFIG_MMC_TIFM_SD=m
1942CONFIG_MEMSTICK=m
1943CONFIG_MEMSTICK_DEBUG=y
1944
1945#
1946# MemoryStick drivers
1947#
1948# CONFIG_MEMSTICK_UNSAFE_RESUME is not set
1949CONFIG_MSPRO_BLOCK=m
1950
1951#
1952# MemoryStick Host Controller Drivers
1953#
1954# CONFIG_MEMSTICK_TIFM_MS is not set
1955# CONFIG_MEMSTICK_JMICRON_38X is not set
1956CONFIG_NEW_LEDS=y
1957CONFIG_LEDS_CLASS=m
1958
1959#
1960# LED drivers
1961#
1962# CONFIG_LEDS_PCA9532 is not set
1963# CONFIG_LEDS_CLEVO_MAIL is not set
1964# CONFIG_LEDS_PCA955X is not set
1965
1966#
1967# LED Triggers
1968#
1969CONFIG_LEDS_TRIGGERS=y
1970# CONFIG_LEDS_TRIGGER_TIMER is not set
1971# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
1972# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
1973# CONFIG_ACCESSIBILITY is not set
1974# CONFIG_INFINIBAND is not set
1975# CONFIG_EDAC is not set
1976CONFIG_RTC_LIB=y
1977CONFIG_RTC_CLASS=y
1978# CONFIG_RTC_HCTOSYS is not set
1979# CONFIG_RTC_DEBUG is not set
1980
1981#
1982# RTC interfaces
1983#
1984CONFIG_RTC_INTF_SYSFS=y
1985CONFIG_RTC_INTF_PROC=y
1986CONFIG_RTC_INTF_DEV=y
1987# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
1988# CONFIG_RTC_DRV_TEST is not set
1989
1990#
1991# I2C RTC drivers
1992#
1993# CONFIG_RTC_DRV_DS1307 is not set
1994# CONFIG_RTC_DRV_DS1374 is not set
1995# CONFIG_RTC_DRV_DS1672 is not set
1996# CONFIG_RTC_DRV_MAX6900 is not set
1997# CONFIG_RTC_DRV_RS5C372 is not set
1998# CONFIG_RTC_DRV_ISL1208 is not set
1999# CONFIG_RTC_DRV_X1205 is not set
2000# CONFIG_RTC_DRV_PCF8563 is not set
2001# CONFIG_RTC_DRV_PCF8583 is not set
2002# CONFIG_RTC_DRV_M41T80 is not set
2003# CONFIG_RTC_DRV_S35390A is not set
2004# CONFIG_RTC_DRV_FM3130 is not set
2005
2006#
2007# SPI RTC drivers
2008#
2009
2010#
2011# Platform RTC drivers
2012#
2013CONFIG_RTC_DRV_CMOS=y
2014# CONFIG_RTC_DRV_DS1511 is not set
2015# CONFIG_RTC_DRV_DS1553 is not set
2016# CONFIG_RTC_DRV_DS1742 is not set
2017# CONFIG_RTC_DRV_STK17TA8 is not set
2018# CONFIG_RTC_DRV_M48T86 is not set
2019# CONFIG_RTC_DRV_M48T59 is not set
2020# CONFIG_RTC_DRV_V3020 is not set
2021
2022#
2023# on-CPU RTC drivers
2024#
2025# CONFIG_DMADEVICES is not set
2026# CONFIG_UIO is not set
2027
2028#
2029# Firmware Drivers
2030#
2031# CONFIG_EDD is not set
2032CONFIG_FIRMWARE_MEMMAP=y
2033# CONFIG_DELL_RBU is not set
2034# CONFIG_DCDBAS is not set
2035# CONFIG_DMIID is not set
2036# CONFIG_ISCSI_IBFT_FIND is not set
2037
2038#
2039# File systems
2040#
2041# CONFIG_EXT2_FS is not set
2042CONFIG_EXT3_FS=y
2043CONFIG_EXT3_FS_XATTR=y
2044CONFIG_EXT3_FS_POSIX_ACL=y
2045CONFIG_EXT3_FS_SECURITY=y
2046# CONFIG_EXT4DEV_FS is not set
2047CONFIG_JBD=y
2048# CONFIG_JBD_DEBUG is not set
2049CONFIG_FS_MBCACHE=y
2050# CONFIG_REISERFS_FS is not set
2051# CONFIG_JFS_FS is not set
2052CONFIG_FS_POSIX_ACL=y
2053# CONFIG_XFS_FS is not set
2054# CONFIG_OCFS2_FS is not set
2055CONFIG_DNOTIFY=y
2056CONFIG_INOTIFY=y
2057CONFIG_INOTIFY_USER=y
2058CONFIG_QUOTA=y
2059CONFIG_QUOTA_NETLINK_INTERFACE=y
2060# CONFIG_PRINT_QUOTA_WARNING is not set
2061# CONFIG_QFMT_V1 is not set
2062CONFIG_QFMT_V2=y
2063CONFIG_QUOTACTL=y
2064# CONFIG_AUTOFS_FS is not set
2065# CONFIG_AUTOFS4_FS is not set
2066CONFIG_FUSE_FS=m
2067CONFIG_GENERIC_ACL=y
2068
2069#
2070# CD-ROM/DVD Filesystems
2071#
2072CONFIG_ISO9660_FS=y
2073CONFIG_JOLIET=y
2074CONFIG_ZISOFS=y
2075CONFIG_UDF_FS=m
2076CONFIG_UDF_NLS=y
2077
2078#
2079# DOS/FAT/NT Filesystems
2080#
2081CONFIG_FAT_FS=y
2082CONFIG_MSDOS_FS=y
2083CONFIG_VFAT_FS=y
2084CONFIG_FAT_DEFAULT_CODEPAGE=437
2085CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
2086# CONFIG_NTFS_FS is not set
2087
2088#
2089# Pseudo filesystems
2090#
2091CONFIG_PROC_FS=y
2092CONFIG_PROC_KCORE=y
2093CONFIG_PROC_VMCORE=y
2094CONFIG_PROC_SYSCTL=y
2095CONFIG_SYSFS=y
2096CONFIG_TMPFS=y
2097CONFIG_TMPFS_POSIX_ACL=y
2098CONFIG_HUGETLBFS=y
2099CONFIG_HUGETLB_PAGE=y
2100CONFIG_CONFIGFS_FS=m
2101
2102#
2103# Miscellaneous filesystems
2104#
2105# CONFIG_ADFS_FS is not set
2106# CONFIG_AFFS_FS is not set
2107# CONFIG_ECRYPT_FS is not set
2108# CONFIG_HFS_FS is not set
2109# CONFIG_HFSPLUS_FS is not set
2110# CONFIG_BEFS_FS is not set
2111# CONFIG_BFS_FS is not set
2112# CONFIG_EFS_FS is not set
2113# CONFIG_CRAMFS is not set
2114# CONFIG_VXFS_FS is not set
2115# CONFIG_MINIX_FS is not set
2116# CONFIG_OMFS_FS is not set
2117# CONFIG_HPFS_FS is not set
2118# CONFIG_QNX4FS_FS is not set
2119# CONFIG_ROMFS_FS is not set
2120# CONFIG_SYSV_FS is not set
2121# CONFIG_UFS_FS is not set
2122CONFIG_NETWORK_FILESYSTEMS=y
2123CONFIG_NFS_FS=y
2124CONFIG_NFS_V3=y
2125# CONFIG_NFS_V3_ACL is not set
2126# CONFIG_NFS_V4 is not set
2127CONFIG_ROOT_NFS=y
2128CONFIG_NFSD=y
2129CONFIG_NFSD_V3=y
2130# CONFIG_NFSD_V3_ACL is not set
2131# CONFIG_NFSD_V4 is not set
2132CONFIG_LOCKD=y
2133CONFIG_LOCKD_V4=y
2134CONFIG_EXPORTFS=y
2135CONFIG_NFS_COMMON=y
2136CONFIG_SUNRPC=y
2137# CONFIG_RPCSEC_GSS_KRB5 is not set
2138# CONFIG_RPCSEC_GSS_SPKM3 is not set
2139# CONFIG_SMB_FS is not set
2140# CONFIG_CIFS is not set
2141# CONFIG_NCP_FS is not set
2142# CONFIG_CODA_FS is not set
2143# CONFIG_AFS_FS is not set
2144
2145#
2146# Partition Types
2147#
2148CONFIG_PARTITION_ADVANCED=y
2149# CONFIG_ACORN_PARTITION is not set
2150CONFIG_OSF_PARTITION=y
2151CONFIG_AMIGA_PARTITION=y
2152# CONFIG_ATARI_PARTITION is not set
2153CONFIG_MAC_PARTITION=y
2154CONFIG_MSDOS_PARTITION=y
2155CONFIG_BSD_DISKLABEL=y
2156CONFIG_MINIX_SUBPARTITION=y
2157CONFIG_SOLARIS_X86_PARTITION=y
2158CONFIG_UNIXWARE_DISKLABEL=y
2159# CONFIG_LDM_PARTITION is not set
2160CONFIG_SGI_PARTITION=y
2161# CONFIG_ULTRIX_PARTITION is not set
2162CONFIG_SUN_PARTITION=y
2163CONFIG_KARMA_PARTITION=y
2164CONFIG_EFI_PARTITION=y
2165# CONFIG_SYSV68_PARTITION is not set
2166CONFIG_NLS=y
2167CONFIG_NLS_DEFAULT="utf8"
2168CONFIG_NLS_CODEPAGE_437=y
2169CONFIG_NLS_CODEPAGE_737=m
2170CONFIG_NLS_CODEPAGE_775=m
2171CONFIG_NLS_CODEPAGE_850=m
2172CONFIG_NLS_CODEPAGE_852=m
2173CONFIG_NLS_CODEPAGE_855=m
2174CONFIG_NLS_CODEPAGE_857=m
2175CONFIG_NLS_CODEPAGE_860=m
2176CONFIG_NLS_CODEPAGE_861=m
2177CONFIG_NLS_CODEPAGE_862=m
2178CONFIG_NLS_CODEPAGE_863=m
2179CONFIG_NLS_CODEPAGE_864=m
2180CONFIG_NLS_CODEPAGE_865=m
2181CONFIG_NLS_CODEPAGE_866=m
2182CONFIG_NLS_CODEPAGE_869=m
2183CONFIG_NLS_CODEPAGE_936=m
2184CONFIG_NLS_CODEPAGE_950=m
2185CONFIG_NLS_CODEPAGE_932=m
2186CONFIG_NLS_CODEPAGE_949=m
2187CONFIG_NLS_CODEPAGE_874=m
2188CONFIG_NLS_ISO8859_8=m
2189CONFIG_NLS_CODEPAGE_1250=m
2190CONFIG_NLS_CODEPAGE_1251=m
2191CONFIG_NLS_ASCII=y
2192CONFIG_NLS_ISO8859_1=m
2193CONFIG_NLS_ISO8859_2=m
2194CONFIG_NLS_ISO8859_3=m
2195CONFIG_NLS_ISO8859_4=m
2196CONFIG_NLS_ISO8859_5=m
2197CONFIG_NLS_ISO8859_6=m
2198CONFIG_NLS_ISO8859_7=m
2199CONFIG_NLS_ISO8859_9=m
2200CONFIG_NLS_ISO8859_13=m
2201CONFIG_NLS_ISO8859_14=m
2202CONFIG_NLS_ISO8859_15=m
2203CONFIG_NLS_KOI8_R=m
2204CONFIG_NLS_KOI8_U=m
2205CONFIG_NLS_UTF8=m
2206# CONFIG_DLM is not set
2207
2208#
2209# Kernel hacking
2210#
2211CONFIG_TRACE_IRQFLAGS_SUPPORT=y
2212CONFIG_PRINTK_TIME=y
2213# CONFIG_ENABLE_WARN_DEPRECATED is not set
2214CONFIG_ENABLE_MUST_CHECK=y
2215CONFIG_FRAME_WARN=1024
2216CONFIG_MAGIC_SYSRQ=y
2217CONFIG_UNUSED_SYMBOLS=y
2218CONFIG_DEBUG_FS=y
2219# CONFIG_HEADERS_CHECK is not set
2220CONFIG_DEBUG_KERNEL=y
2221CONFIG_DEBUG_SHIRQ=y
2222CONFIG_DETECT_SOFTLOCKUP=y
2223# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
2224CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
2225CONFIG_SCHED_DEBUG=y
2226CONFIG_SCHEDSTATS=y
2227CONFIG_TIMER_STATS=y
2228# CONFIG_DEBUG_OBJECTS is not set
2229# CONFIG_DEBUG_SLAB is not set
2230# CONFIG_DEBUG_RT_MUTEXES is not set
2231# CONFIG_RT_MUTEX_TESTER is not set
2232# CONFIG_DEBUG_SPINLOCK is not set
2233# CONFIG_DEBUG_MUTEXES is not set
2234# CONFIG_DEBUG_LOCK_ALLOC is not set
2235# CONFIG_PROVE_LOCKING is not set
2236# CONFIG_LOCK_STAT is not set
2237CONFIG_DEBUG_SPINLOCK_SLEEP=y
2238# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
2239CONFIG_STACKTRACE=y
2240# CONFIG_DEBUG_KOBJECT is not set
2241# CONFIG_DEBUG_HIGHMEM is not set
2242CONFIG_DEBUG_BUGVERBOSE=y
2243# CONFIG_DEBUG_INFO is not set
2244# CONFIG_DEBUG_VM is not set
2245# CONFIG_DEBUG_WRITECOUNT is not set
2246CONFIG_DEBUG_MEMORY_INIT=y
2247CONFIG_DEBUG_LIST=y
2248# CONFIG_DEBUG_SG is not set
2249CONFIG_FRAME_POINTER=y
2250CONFIG_BOOT_PRINTK_DELAY=y
2251# CONFIG_RCU_TORTURE_TEST is not set
2252# CONFIG_BACKTRACE_SELF_TEST is not set
2253# CONFIG_FAULT_INJECTION is not set
2254CONFIG_LATENCYTOP=y
2255CONFIG_SYSCTL_SYSCALL_CHECK=y
2256CONFIG_HAVE_FTRACE=y
2257CONFIG_HAVE_DYNAMIC_FTRACE=y
2258CONFIG_TRACING=y
2259# CONFIG_FTRACE is not set
2260# CONFIG_IRQSOFF_TRACER is not set
2261CONFIG_SYSPROF_TRACER=y
2262# CONFIG_SCHED_TRACER is not set
2263# CONFIG_CONTEXT_SWITCH_TRACER is not set
2264# CONFIG_FTRACE_STARTUP_TEST is not set
2265# CONFIG_PROVIDE_OHCI1394_DMA_INIT is not set
2266# CONFIG_SAMPLES is not set
2267CONFIG_HAVE_ARCH_KGDB=y
2268# CONFIG_KGDB is not set
2269# CONFIG_STRICT_DEVMEM is not set
2270CONFIG_X86_VERBOSE_BOOTUP=y
2271CONFIG_EARLY_PRINTK=y
2272# CONFIG_DEBUG_STACKOVERFLOW is not set
2273# CONFIG_DEBUG_STACK_USAGE is not set
2274# CONFIG_DEBUG_PAGEALLOC is not set
2275# CONFIG_DEBUG_PER_CPU_MAPS is not set
2276CONFIG_X86_PTDUMP=y
2277CONFIG_DEBUG_RODATA=y
2278# CONFIG_DEBUG_RODATA_TEST is not set
2279# CONFIG_DEBUG_NX_TEST is not set
2280# CONFIG_4KSTACKS is not set
2281CONFIG_DOUBLEFAULT=y
2282# CONFIG_MMIOTRACE is not set
2283CONFIG_IO_DELAY_TYPE_0X80=0
2284CONFIG_IO_DELAY_TYPE_0XED=1
2285CONFIG_IO_DELAY_TYPE_UDELAY=2
2286CONFIG_IO_DELAY_TYPE_NONE=3
2287CONFIG_IO_DELAY_0X80=y
2288# CONFIG_IO_DELAY_0XED is not set
2289# CONFIG_IO_DELAY_UDELAY is not set
2290# CONFIG_IO_DELAY_NONE is not set
2291CONFIG_DEFAULT_IO_DELAY_TYPE=0
2292CONFIG_DEBUG_BOOT_PARAMS=y
2293# CONFIG_CPA_DEBUG is not set
2294# CONFIG_OPTIMIZE_INLINING is not set
2295
2296#
2297# Security options
2298#
2299CONFIG_KEYS=y
2300CONFIG_KEYS_DEBUG_PROC_KEYS=y
2301CONFIG_SECURITY=y
2302CONFIG_SECURITY_NETWORK=y
2303CONFIG_SECURITY_NETWORK_XFRM=y
2304CONFIG_SECURITY_FILE_CAPABILITIES=y
2305# CONFIG_SECURITY_ROOTPLUG is not set
2306CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=65536
2307# CONFIG_SECURITY_SELINUX is not set
2308# CONFIG_SECURITY_SMACK is not set
2309CONFIG_CRYPTO=y
2310
2311#
2312# Crypto core or helper
2313#
2314CONFIG_CRYPTO_ALGAPI=y
2315CONFIG_CRYPTO_AEAD=m
2316CONFIG_CRYPTO_BLKCIPHER=m
2317CONFIG_CRYPTO_HASH=y
2318CONFIG_CRYPTO_MANAGER=y
2319CONFIG_CRYPTO_GF128MUL=m
2320CONFIG_CRYPTO_NULL=m
2321# CONFIG_CRYPTO_CRYPTD is not set
2322CONFIG_CRYPTO_AUTHENC=m
2323CONFIG_CRYPTO_TEST=m
2324
2325#
2326# Authenticated Encryption with Associated Data
2327#
2328CONFIG_CRYPTO_CCM=m
2329CONFIG_CRYPTO_GCM=m
2330CONFIG_CRYPTO_SEQIV=m
2331
2332#
2333# Block modes
2334#
2335CONFIG_CRYPTO_CBC=m
2336CONFIG_CRYPTO_CTR=m
2337# CONFIG_CRYPTO_CTS is not set
2338CONFIG_CRYPTO_ECB=m
2339CONFIG_CRYPTO_LRW=m
2340CONFIG_CRYPTO_PCBC=m
2341CONFIG_CRYPTO_XTS=m
2342
2343#
2344# Hash modes
2345#
2346CONFIG_CRYPTO_HMAC=y
2347CONFIG_CRYPTO_XCBC=m
2348
2349#
2350# Digest
2351#
2352CONFIG_CRYPTO_CRC32C=m
2353CONFIG_CRYPTO_MD4=m
2354CONFIG_CRYPTO_MD5=y
2355CONFIG_CRYPTO_MICHAEL_MIC=m
2356# CONFIG_CRYPTO_RMD128 is not set
2357# CONFIG_CRYPTO_RMD160 is not set
2358# CONFIG_CRYPTO_RMD256 is not set
2359# CONFIG_CRYPTO_RMD320 is not set
2360CONFIG_CRYPTO_SHA1=y
2361CONFIG_CRYPTO_SHA256=m
2362CONFIG_CRYPTO_SHA512=m
2363CONFIG_CRYPTO_TGR192=m
2364CONFIG_CRYPTO_WP512=m
2365
2366#
2367# Ciphers
2368#
2369CONFIG_CRYPTO_AES=m
2370# CONFIG_CRYPTO_AES_586 is not set
2371CONFIG_CRYPTO_ANUBIS=m
2372CONFIG_CRYPTO_ARC4=m
2373CONFIG_CRYPTO_BLOWFISH=m
2374CONFIG_CRYPTO_CAMELLIA=m
2375CONFIG_CRYPTO_CAST5=m
2376CONFIG_CRYPTO_CAST6=m
2377CONFIG_CRYPTO_DES=m
2378CONFIG_CRYPTO_FCRYPT=m
2379CONFIG_CRYPTO_KHAZAD=m
2380CONFIG_CRYPTO_SALSA20=m
2381# CONFIG_CRYPTO_SALSA20_586 is not set
2382CONFIG_CRYPTO_SEED=m
2383CONFIG_CRYPTO_SERPENT=m
2384CONFIG_CRYPTO_TEA=m
2385CONFIG_CRYPTO_TWOFISH=m
2386CONFIG_CRYPTO_TWOFISH_COMMON=m
2387# CONFIG_CRYPTO_TWOFISH_586 is not set
2388
2389#
2390# Compression
2391#
2392CONFIG_CRYPTO_DEFLATE=m
2393# CONFIG_CRYPTO_LZO is not set
2394CONFIG_CRYPTO_HW=y
2395# CONFIG_CRYPTO_DEV_PADLOCK is not set
2396# CONFIG_CRYPTO_DEV_GEODE is not set
2397# CONFIG_CRYPTO_DEV_HIFN_795X is not set
2398CONFIG_HAVE_KVM=y
2399# CONFIG_VIRTUALIZATION is not set
2400
2401#
2402# Library routines
2403#
2404CONFIG_BITREVERSE=y
2405CONFIG_GENERIC_FIND_FIRST_BIT=y
2406CONFIG_GENERIC_FIND_NEXT_BIT=y
2407CONFIG_CRC_CCITT=m
2408CONFIG_CRC16=m
2409CONFIG_CRC_T10DIF=y
2410CONFIG_CRC_ITU_T=m
2411CONFIG_CRC32=y
2412# CONFIG_CRC7 is not set
2413CONFIG_LIBCRC32C=m
2414CONFIG_AUDIT_GENERIC=y
2415CONFIG_ZLIB_INFLATE=y
2416CONFIG_ZLIB_DEFLATE=m
2417CONFIG_TEXTSEARCH=y
2418CONFIG_TEXTSEARCH_KMP=m
2419CONFIG_TEXTSEARCH_BM=m
2420CONFIG_TEXTSEARCH_FSM=m
2421CONFIG_PLIST=y
2422CONFIG_HAS_IOMEM=y
2423CONFIG_HAS_IOPORT=y
2424CONFIG_HAS_DMA=y
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27/0001-drm-remove-define-for-non-linux-systems.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27/0001-drm-remove-define-for-non-linux-systems.patch
new file mode 100644
index 0000000000..588c1af70b
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27/0001-drm-remove-define-for-non-linux-systems.patch
@@ -0,0 +1,48 @@
1commit 2e6ec7cdc09f36be1cbe9aeaccfc45f307fc0060
2Author: Carlos R. Mafra <crmafra2@gmail.com>
3Date: Wed Jul 30 12:29:37 2008 -0700
4
5 drm: remove #define's for non-linux systems
6
7 There is no point in considering FreeBSD et al. in the linux kernel
8 source code.
9
10 Signed-off-by: Carlos R. Mafra <crmafra@gmail.com>
11 Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
12 Signed-off-by: Dave Airlie <airlied@redhat.com>
13
14diff --git a/include/drm/drm.h b/include/drm/drm.h
15index 38d3c6b..0864c69 100644
16--- a/include/drm/drm.h
17+++ b/include/drm/drm.h
18@@ -36,7 +36,6 @@
19 #ifndef _DRM_H_
20 #define _DRM_H_
21
22-#if defined(__linux__)
23 #if defined(__KERNEL__)
24 #endif
25 #include <asm/ioctl.h> /* For _IO* macros */
26@@ -46,22 +45,6 @@
27 #define DRM_IOC_WRITE _IOC_WRITE
28 #define DRM_IOC_READWRITE _IOC_READ|_IOC_WRITE
29 #define DRM_IOC(dir, group, nr, size) _IOC(dir, group, nr, size)
30-#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
31-#if defined(__FreeBSD__) && defined(IN_MODULE)
32-/* Prevent name collision when including sys/ioccom.h */
33-#undef ioctl
34-#include <sys/ioccom.h>
35-#define ioctl(a,b,c) xf86ioctl(a,b,c)
36-#else
37-#include <sys/ioccom.h>
38-#endif /* __FreeBSD__ && xf86ioctl */
39-#define DRM_IOCTL_NR(n) ((n) & 0xff)
40-#define DRM_IOC_VOID IOC_VOID
41-#define DRM_IOC_READ IOC_OUT
42-#define DRM_IOC_WRITE IOC_IN
43-#define DRM_IOC_READWRITE IOC_INOUT
44-#define DRM_IOC(dir, group, nr, size) _IOC(dir, group, nr, size)
45-#endif
46
47 #define DRM_MAJOR 226
48 #define DRM_MAX_MINOR 15
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27/0002-i915-remove-settable-use_mi_batchbuffer_start.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27/0002-i915-remove-settable-use_mi_batchbuffer_start.patch
new file mode 100644
index 0000000000..f3c41f7cbd
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27/0002-i915-remove-settable-use_mi_batchbuffer_start.patch
@@ -0,0 +1,60 @@
1commit 91019197abbfde388d0b71b0fc8979a936c23fe3
2Author: Keith Packard <keithp@keithp.com>
3Date: Wed Jul 30 12:28:47 2008 -0700
4
5 i915: remove settable use_mi_batchbuffer_start
6
7 The driver can know what hardware requires MI_BATCH_BUFFER vs
8 MI_BATCH_BUFFER_START; there's no reason to let user mode configure this.
9
10 Signed-off-by: Eric Anholt <eric@anholt.net>
11 Signed-off-by: Dave Airlie <airlied@redhat.com>
12
13diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
14index 8897434..24adbde 100644
15--- a/drivers/gpu/drm/i915/i915_dma.c
16+++ b/drivers/gpu/drm/i915/i915_dma.c
17@@ -159,13 +159,6 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
18 dev_priv->current_page = 0;
19 dev_priv->sarea_priv->pf_current_page = dev_priv->current_page;
20
21- /* We are using separate values as placeholders for mechanisms for
22- * private backbuffer/depthbuffer usage.
23- */
24- dev_priv->use_mi_batchbuffer_start = 0;
25- if (IS_I965G(dev)) /* 965 doesn't support older method */
26- dev_priv->use_mi_batchbuffer_start = 1;
27-
28 /* Allow hardware batchbuffers unless told otherwise.
29 */
30 dev_priv->allow_batchbuffer = 1;
31@@ -486,7 +479,7 @@ static int i915_dispatch_batchbuffer(struct drm_device * dev,
32 return ret;
33 }
34
35- if (dev_priv->use_mi_batchbuffer_start) {
36+ if (!IS_I830(dev) && !IS_845G(dev)) {
37 BEGIN_LP_RING(2);
38 if (IS_I965G(dev)) {
39 OUT_RING(MI_BATCH_BUFFER_START | (2 << 6) | MI_BATCH_NON_SECURE_I965);
40@@ -697,8 +690,6 @@ static int i915_setparam(struct drm_device *dev, void *data,
41
42 switch (param->param) {
43 case I915_SETPARAM_USE_MI_BATCHBUFFER_START:
44- if (!IS_I965G(dev))
45- dev_priv->use_mi_batchbuffer_start = param->value;
46 break;
47 case I915_SETPARAM_TEX_LRU_LOG_GRANULARITY:
48 dev_priv->tex_lru_log_granularity = param->value;
49diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
50index d7326d9..2d441d3 100644
51--- a/drivers/gpu/drm/i915/i915_drv.h
52+++ b/drivers/gpu/drm/i915/i915_drv.h
53@@ -99,7 +99,6 @@ typedef struct drm_i915_private {
54 int front_offset;
55 int current_page;
56 int page_flipping;
57- int use_mi_batchbuffer_start;
58
59 wait_queue_head_t irq_queue;
60 atomic_t irq_received;
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27/0003-i915-Ignore-X-server-provided-mmio-address.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27/0003-i915-Ignore-X-server-provided-mmio-address.patch
new file mode 100644
index 0000000000..9f7e0b4bcd
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27/0003-i915-Ignore-X-server-provided-mmio-address.patch
@@ -0,0 +1,41 @@
1commit 20ae3cf7d4a9ae8d23bcffa67c9a34fc2640d217
2Author: Keith Packard <keithp@keithp.com>
3Date: Wed Jul 30 12:36:08 2008 -0700
4
5 i915: Ignore X server provided mmio address
6
7 It is already correctly detected by the kernel for use in suspend/resume.
8
9 Signed-off-by: Eric Anholt <eric@anholt.net>
10 Signed-off-by: Dave Airlie <airlied@redhat.com>
11
12diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
13index 24adbde..01a869b 100644
14--- a/drivers/gpu/drm/i915/i915_dma.c
15+++ b/drivers/gpu/drm/i915/i915_dma.c
16@@ -121,13 +121,6 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
17 return -EINVAL;
18 }
19
20- dev_priv->mmio_map = drm_core_findmap(dev, init->mmio_offset);
21- if (!dev_priv->mmio_map) {
22- i915_dma_cleanup(dev);
23- DRM_ERROR("can not find mmio map!\n");
24- return -EINVAL;
25- }
26-
27 dev_priv->sarea_priv = (drm_i915_sarea_t *)
28 ((u8 *) dev_priv->sarea->handle + init->sarea_priv_offset);
29
30@@ -194,11 +187,6 @@ static int i915_dma_resume(struct drm_device * dev)
31 return -EINVAL;
32 }
33
34- if (!dev_priv->mmio_map) {
35- DRM_ERROR("can not find mmio map!\n");
36- return -EINVAL;
37- }
38-
39 if (dev_priv->ring.map.handle == NULL) {
40 DRM_ERROR("can not ioremap virtual address for"
41 " ring buffer\n");
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27/0004-i915-Use-more-consistent-names-for-regs-and-store.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27/0004-i915-Use-more-consistent-names-for-regs-and-store.patch
new file mode 100644
index 0000000000..f7a310ea60
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27/0004-i915-Use-more-consistent-names-for-regs-and-store.patch
@@ -0,0 +1,2746 @@
1commit 573e91575687018b4307f53a50f4da0084dbdf3d
2Author: Jesse Barnes <jbarnes@virtuousgeek.org>
3Date: Tue Jul 29 11:54:06 2008 -0700
4
5 i915: Use more consistent names for regs, and store them in a separate file.
6
7 Signed-off-by: Eric Anholt <eric@anholt.net>
8 Signed-off-by: Dave Airlie <airlied@redhat.com>
9
10diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
11index 01a869b..7be580b 100644
12--- a/drivers/gpu/drm/i915/i915_dma.c
13+++ b/drivers/gpu/drm/i915/i915_dma.c
14@@ -40,11 +40,11 @@ int i915_wait_ring(struct drm_device * dev, int n, const char *caller)
15 {
16 drm_i915_private_t *dev_priv = dev->dev_private;
17 drm_i915_ring_buffer_t *ring = &(dev_priv->ring);
18- u32 last_head = I915_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
19+ u32 last_head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
20 int i;
21
22 for (i = 0; i < 10000; i++) {
23- ring->head = I915_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
24+ ring->head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
25 ring->space = ring->head - (ring->tail + 8);
26 if (ring->space < 0)
27 ring->space += ring->Size;
28@@ -67,8 +67,8 @@ void i915_kernel_lost_context(struct drm_device * dev)
29 drm_i915_private_t *dev_priv = dev->dev_private;
30 drm_i915_ring_buffer_t *ring = &(dev_priv->ring);
31
32- ring->head = I915_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
33- ring->tail = I915_READ(LP_RING + RING_TAIL) & TAIL_ADDR;
34+ ring->head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
35+ ring->tail = I915_READ(PRB0_TAIL) & TAIL_ADDR;
36 ring->space = ring->head - (ring->tail + 8);
37 if (ring->space < 0)
38 ring->space += ring->Size;
39@@ -98,13 +98,13 @@ static int i915_dma_cleanup(struct drm_device * dev)
40 drm_pci_free(dev, dev_priv->status_page_dmah);
41 dev_priv->status_page_dmah = NULL;
42 /* Need to rewrite hardware status page */
43- I915_WRITE(0x02080, 0x1ffff000);
44+ I915_WRITE(HWS_PGA, 0x1ffff000);
45 }
46
47 if (dev_priv->status_gfx_addr) {
48 dev_priv->status_gfx_addr = 0;
49 drm_core_ioremapfree(&dev_priv->hws_map, dev);
50- I915_WRITE(0x2080, 0x1ffff000);
51+ I915_WRITE(HWS_PGA, 0x1ffff000);
52 }
53
54 return 0;
55@@ -170,7 +170,7 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
56 dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr;
57
58 memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
59- I915_WRITE(0x02080, dev_priv->dma_status_page);
60+ I915_WRITE(HWS_PGA, dev_priv->dma_status_page);
61 }
62 DRM_DEBUG("Enabled hardware status page\n");
63 return 0;
64@@ -201,9 +201,9 @@ static int i915_dma_resume(struct drm_device * dev)
65 DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page);
66
67 if (dev_priv->status_gfx_addr != 0)
68- I915_WRITE(0x02080, dev_priv->status_gfx_addr);
69+ I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr);
70 else
71- I915_WRITE(0x02080, dev_priv->dma_status_page);
72+ I915_WRITE(HWS_PGA, dev_priv->dma_status_page);
73 DRM_DEBUG("Enabled hardware status page\n");
74
75 return 0;
76@@ -402,8 +402,8 @@ static void i915_emit_breadcrumb(struct drm_device *dev)
77 dev_priv->sarea_priv->last_enqueue = dev_priv->counter = 1;
78
79 BEGIN_LP_RING(4);
80- OUT_RING(CMD_STORE_DWORD_IDX);
81- OUT_RING(20);
82+ OUT_RING(MI_STORE_DWORD_INDEX);
83+ OUT_RING(5 << MI_STORE_DWORD_INDEX_SHIFT);
84 OUT_RING(dev_priv->counter);
85 OUT_RING(0);
86 ADVANCE_LP_RING();
87@@ -505,7 +505,7 @@ static int i915_dispatch_flip(struct drm_device * dev)
88 i915_kernel_lost_context(dev);
89
90 BEGIN_LP_RING(2);
91- OUT_RING(INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE);
92+ OUT_RING(MI_FLUSH | MI_READ_FLUSH);
93 OUT_RING(0);
94 ADVANCE_LP_RING();
95
96@@ -530,8 +530,8 @@ static int i915_dispatch_flip(struct drm_device * dev)
97 dev_priv->sarea_priv->last_enqueue = dev_priv->counter++;
98
99 BEGIN_LP_RING(4);
100- OUT_RING(CMD_STORE_DWORD_IDX);
101- OUT_RING(20);
102+ OUT_RING(MI_STORE_DWORD_INDEX);
103+ OUT_RING(5 << MI_STORE_DWORD_INDEX_SHIFT);
104 OUT_RING(dev_priv->counter);
105 OUT_RING(0);
106 ADVANCE_LP_RING();
107@@ -728,8 +728,8 @@ static int i915_set_status_page(struct drm_device *dev, void *data,
108 dev_priv->hw_status_page = dev_priv->hws_map.handle;
109
110 memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
111- I915_WRITE(0x02080, dev_priv->status_gfx_addr);
112- DRM_DEBUG("load hws 0x2080 with gfx mem 0x%x\n",
113+ I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr);
114+ DRM_DEBUG("load hws HWS_PGA with gfx mem 0x%x\n",
115 dev_priv->status_gfx_addr);
116 DRM_DEBUG("load hws at %p\n", dev_priv->hw_status_page);
117 return 0;
118diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
119index 93aed1c..6c99aab 100644
120--- a/drivers/gpu/drm/i915/i915_drv.c
121+++ b/drivers/gpu/drm/i915/i915_drv.c
122@@ -279,13 +279,13 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state)
123 dev_priv->saveDSPASTRIDE = I915_READ(DSPASTRIDE);
124 dev_priv->saveDSPASIZE = I915_READ(DSPASIZE);
125 dev_priv->saveDSPAPOS = I915_READ(DSPAPOS);
126- dev_priv->saveDSPABASE = I915_READ(DSPABASE);
127+ dev_priv->saveDSPAADDR = I915_READ(DSPAADDR);
128 if (IS_I965G(dev)) {
129 dev_priv->saveDSPASURF = I915_READ(DSPASURF);
130 dev_priv->saveDSPATILEOFF = I915_READ(DSPATILEOFF);
131 }
132 i915_save_palette(dev, PIPE_A);
133- dev_priv->savePIPEASTAT = I915_READ(I915REG_PIPEASTAT);
134+ dev_priv->savePIPEASTAT = I915_READ(PIPEASTAT);
135
136 /* Pipe & plane B info */
137 dev_priv->savePIPEBCONF = I915_READ(PIPEBCONF);
138@@ -307,13 +307,13 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state)
139 dev_priv->saveDSPBSTRIDE = I915_READ(DSPBSTRIDE);
140 dev_priv->saveDSPBSIZE = I915_READ(DSPBSIZE);
141 dev_priv->saveDSPBPOS = I915_READ(DSPBPOS);
142- dev_priv->saveDSPBBASE = I915_READ(DSPBBASE);
143+ dev_priv->saveDSPBADDR = I915_READ(DSPBADDR);
144 if (IS_I965GM(dev) || IS_IGD_GM(dev)) {
145 dev_priv->saveDSPBSURF = I915_READ(DSPBSURF);
146 dev_priv->saveDSPBTILEOFF = I915_READ(DSPBTILEOFF);
147 }
148 i915_save_palette(dev, PIPE_B);
149- dev_priv->savePIPEBSTAT = I915_READ(I915REG_PIPEBSTAT);
150+ dev_priv->savePIPEBSTAT = I915_READ(PIPEBSTAT);
151
152 /* CRT state */
153 dev_priv->saveADPA = I915_READ(ADPA);
154@@ -328,9 +328,9 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state)
155 dev_priv->saveLVDS = I915_READ(LVDS);
156 if (!IS_I830(dev) && !IS_845G(dev))
157 dev_priv->savePFIT_CONTROL = I915_READ(PFIT_CONTROL);
158- dev_priv->saveLVDSPP_ON = I915_READ(LVDSPP_ON);
159- dev_priv->saveLVDSPP_OFF = I915_READ(LVDSPP_OFF);
160- dev_priv->savePP_CYCLE = I915_READ(PP_CYCLE);
161+ dev_priv->savePP_ON_DELAYS = I915_READ(PP_ON_DELAYS);
162+ dev_priv->savePP_OFF_DELAYS = I915_READ(PP_OFF_DELAYS);
163+ dev_priv->savePP_DIVISOR = I915_READ(PP_DIVISOR);
164
165 /* FIXME: save TV & SDVO state */
166
167@@ -341,19 +341,19 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state)
168 dev_priv->saveFBC_CONTROL = I915_READ(FBC_CONTROL);
169
170 /* Interrupt state */
171- dev_priv->saveIIR = I915_READ(I915REG_INT_IDENTITY_R);
172- dev_priv->saveIER = I915_READ(I915REG_INT_ENABLE_R);
173- dev_priv->saveIMR = I915_READ(I915REG_INT_MASK_R);
174+ dev_priv->saveIIR = I915_READ(IIR);
175+ dev_priv->saveIER = I915_READ(IER);
176+ dev_priv->saveIMR = I915_READ(IMR);
177
178 /* VGA state */
179- dev_priv->saveVCLK_DIVISOR_VGA0 = I915_READ(VCLK_DIVISOR_VGA0);
180- dev_priv->saveVCLK_DIVISOR_VGA1 = I915_READ(VCLK_DIVISOR_VGA1);
181- dev_priv->saveVCLK_POST_DIV = I915_READ(VCLK_POST_DIV);
182+ dev_priv->saveVGA0 = I915_READ(VGA0);
183+ dev_priv->saveVGA1 = I915_READ(VGA1);
184+ dev_priv->saveVGA_PD = I915_READ(VGA_PD);
185 dev_priv->saveVGACNTRL = I915_READ(VGACNTRL);
186
187 /* Clock gating state */
188 dev_priv->saveD_STATE = I915_READ(D_STATE);
189- dev_priv->saveDSPCLK_GATE_D = I915_READ(DSPCLK_GATE_D);
190+ dev_priv->saveCG_2D_DIS = I915_READ(CG_2D_DIS);
191
192 /* Cache mode state */
193 dev_priv->saveCACHE_MODE_0 = I915_READ(CACHE_MODE_0);
194@@ -363,7 +363,7 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state)
195
196 /* Scratch space */
197 for (i = 0; i < 16; i++) {
198- dev_priv->saveSWF0[i] = I915_READ(SWF0 + (i << 2));
199+ dev_priv->saveSWF0[i] = I915_READ(SWF00 + (i << 2));
200 dev_priv->saveSWF1[i] = I915_READ(SWF10 + (i << 2));
201 }
202 for (i = 0; i < 3; i++)
203@@ -424,7 +424,7 @@ static int i915_resume(struct drm_device *dev)
204 I915_WRITE(DSPASIZE, dev_priv->saveDSPASIZE);
205 I915_WRITE(DSPAPOS, dev_priv->saveDSPAPOS);
206 I915_WRITE(PIPEASRC, dev_priv->savePIPEASRC);
207- I915_WRITE(DSPABASE, dev_priv->saveDSPABASE);
208+ I915_WRITE(DSPAADDR, dev_priv->saveDSPAADDR);
209 I915_WRITE(DSPASTRIDE, dev_priv->saveDSPASTRIDE);
210 if (IS_I965G(dev)) {
211 I915_WRITE(DSPASURF, dev_priv->saveDSPASURF);
212@@ -436,7 +436,7 @@ static int i915_resume(struct drm_device *dev)
213 i915_restore_palette(dev, PIPE_A);
214 /* Enable the plane */
215 I915_WRITE(DSPACNTR, dev_priv->saveDSPACNTR);
216- I915_WRITE(DSPABASE, I915_READ(DSPABASE));
217+ I915_WRITE(DSPAADDR, I915_READ(DSPAADDR));
218
219 /* Pipe & plane B info */
220 if (dev_priv->saveDPLL_B & DPLL_VCO_ENABLE) {
221@@ -466,7 +466,7 @@ static int i915_resume(struct drm_device *dev)
222 I915_WRITE(DSPBSIZE, dev_priv->saveDSPBSIZE);
223 I915_WRITE(DSPBPOS, dev_priv->saveDSPBPOS);
224 I915_WRITE(PIPEBSRC, dev_priv->savePIPEBSRC);
225- I915_WRITE(DSPBBASE, dev_priv->saveDSPBBASE);
226+ I915_WRITE(DSPBADDR, dev_priv->saveDSPBADDR);
227 I915_WRITE(DSPBSTRIDE, dev_priv->saveDSPBSTRIDE);
228 if (IS_I965G(dev)) {
229 I915_WRITE(DSPBSURF, dev_priv->saveDSPBSURF);
230@@ -478,7 +478,7 @@ static int i915_resume(struct drm_device *dev)
231 i915_restore_palette(dev, PIPE_B);
232 /* Enable the plane */
233 I915_WRITE(DSPBCNTR, dev_priv->saveDSPBCNTR);
234- I915_WRITE(DSPBBASE, I915_READ(DSPBBASE));
235+ I915_WRITE(DSPBADDR, I915_READ(DSPBADDR));
236
237 /* CRT state */
238 I915_WRITE(ADPA, dev_priv->saveADPA);
239@@ -493,9 +493,9 @@ static int i915_resume(struct drm_device *dev)
240
241 I915_WRITE(PFIT_PGM_RATIOS, dev_priv->savePFIT_PGM_RATIOS);
242 I915_WRITE(BLC_PWM_CTL, dev_priv->saveBLC_PWM_CTL);
243- I915_WRITE(LVDSPP_ON, dev_priv->saveLVDSPP_ON);
244- I915_WRITE(LVDSPP_OFF, dev_priv->saveLVDSPP_OFF);
245- I915_WRITE(PP_CYCLE, dev_priv->savePP_CYCLE);
246+ I915_WRITE(PP_ON_DELAYS, dev_priv->savePP_ON_DELAYS);
247+ I915_WRITE(PP_OFF_DELAYS, dev_priv->savePP_OFF_DELAYS);
248+ I915_WRITE(PP_DIVISOR, dev_priv->savePP_DIVISOR);
249 I915_WRITE(PP_CONTROL, dev_priv->savePP_CONTROL);
250
251 /* FIXME: restore TV & SDVO state */
252@@ -508,14 +508,14 @@ static int i915_resume(struct drm_device *dev)
253
254 /* VGA state */
255 I915_WRITE(VGACNTRL, dev_priv->saveVGACNTRL);
256- I915_WRITE(VCLK_DIVISOR_VGA0, dev_priv->saveVCLK_DIVISOR_VGA0);
257- I915_WRITE(VCLK_DIVISOR_VGA1, dev_priv->saveVCLK_DIVISOR_VGA1);
258- I915_WRITE(VCLK_POST_DIV, dev_priv->saveVCLK_POST_DIV);
259+ I915_WRITE(VGA0, dev_priv->saveVGA0);
260+ I915_WRITE(VGA1, dev_priv->saveVGA1);
261+ I915_WRITE(VGA_PD, dev_priv->saveVGA_PD);
262 udelay(150);
263
264 /* Clock gating state */
265 I915_WRITE (D_STATE, dev_priv->saveD_STATE);
266- I915_WRITE (DSPCLK_GATE_D, dev_priv->saveDSPCLK_GATE_D);
267+ I915_WRITE(CG_2D_DIS, dev_priv->saveCG_2D_DIS);
268
269 /* Cache mode state */
270 I915_WRITE (CACHE_MODE_0, dev_priv->saveCACHE_MODE_0 | 0xffff0000);
271@@ -524,7 +524,7 @@ static int i915_resume(struct drm_device *dev)
272 I915_WRITE (MI_ARB_STATE, dev_priv->saveMI_ARB_STATE | 0xffff0000);
273
274 for (i = 0; i < 16; i++) {
275- I915_WRITE(SWF0 + (i << 2), dev_priv->saveSWF0[i]);
276+ I915_WRITE(SWF00 + (i << 2), dev_priv->saveSWF0[i]);
277 I915_WRITE(SWF10 + (i << 2), dev_priv->saveSWF1[i+7]);
278 }
279 for (i = 0; i < 3; i++)
280diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
281index 2d441d3..afb51a3 100644
282--- a/drivers/gpu/drm/i915/i915_drv.h
283+++ b/drivers/gpu/drm/i915/i915_drv.h
284@@ -30,6 +30,8 @@
285 #ifndef _I915_DRV_H_
286 #define _I915_DRV_H_
287
288+#include "i915_reg.h"
289+
290 /* General customization:
291 */
292
293@@ -138,7 +140,7 @@ typedef struct drm_i915_private {
294 u32 saveDSPASTRIDE;
295 u32 saveDSPASIZE;
296 u32 saveDSPAPOS;
297- u32 saveDSPABASE;
298+ u32 saveDSPAADDR;
299 u32 saveDSPASURF;
300 u32 saveDSPATILEOFF;
301 u32 savePFIT_PGM_RATIOS;
302@@ -159,24 +161,24 @@ typedef struct drm_i915_private {
303 u32 saveDSPBSTRIDE;
304 u32 saveDSPBSIZE;
305 u32 saveDSPBPOS;
306- u32 saveDSPBBASE;
307+ u32 saveDSPBADDR;
308 u32 saveDSPBSURF;
309 u32 saveDSPBTILEOFF;
310- u32 saveVCLK_DIVISOR_VGA0;
311- u32 saveVCLK_DIVISOR_VGA1;
312- u32 saveVCLK_POST_DIV;
313+ u32 saveVGA0;
314+ u32 saveVGA1;
315+ u32 saveVGA_PD;
316 u32 saveVGACNTRL;
317 u32 saveADPA;
318 u32 saveLVDS;
319- u32 saveLVDSPP_ON;
320- u32 saveLVDSPP_OFF;
321+ u32 savePP_ON_DELAYS;
322+ u32 savePP_OFF_DELAYS;
323 u32 saveDVOA;
324 u32 saveDVOB;
325 u32 saveDVOC;
326 u32 savePP_ON;
327 u32 savePP_OFF;
328 u32 savePP_CONTROL;
329- u32 savePP_CYCLE;
330+ u32 savePP_DIVISOR;
331 u32 savePFIT_CONTROL;
332 u32 save_palette_a[256];
333 u32 save_palette_b[256];
334@@ -189,7 +191,7 @@ typedef struct drm_i915_private {
335 u32 saveIMR;
336 u32 saveCACHE_MODE_0;
337 u32 saveD_STATE;
338- u32 saveDSPCLK_GATE_D;
339+ u32 saveCG_2D_DIS;
340 u32 saveMI_ARB_STATE;
341 u32 saveSWF0[16];
342 u32 saveSWF1[16];
343@@ -283,816 +285,26 @@ extern void i915_mem_release(struct drm_device * dev,
344 if (I915_VERBOSE) DRM_DEBUG("ADVANCE_LP_RING %x\n", outring); \
345 dev_priv->ring.tail = outring; \
346 dev_priv->ring.space -= outcount * 4; \
347- I915_WRITE(LP_RING + RING_TAIL, outring); \
348+ I915_WRITE(PRB0_TAIL, outring); \
349 } while(0)
350
351-extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
352-
353-/* Extended config space */
354-#define LBB 0xf4
355-
356-/* VGA stuff */
357-
358-#define VGA_ST01_MDA 0x3ba
359-#define VGA_ST01_CGA 0x3da
360-
361-#define VGA_MSR_WRITE 0x3c2
362-#define VGA_MSR_READ 0x3cc
363-#define VGA_MSR_MEM_EN (1<<1)
364-#define VGA_MSR_CGA_MODE (1<<0)
365-
366-#define VGA_SR_INDEX 0x3c4
367-#define VGA_SR_DATA 0x3c5
368-
369-#define VGA_AR_INDEX 0x3c0
370-#define VGA_AR_VID_EN (1<<5)
371-#define VGA_AR_DATA_WRITE 0x3c0
372-#define VGA_AR_DATA_READ 0x3c1
373-
374-#define VGA_GR_INDEX 0x3ce
375-#define VGA_GR_DATA 0x3cf
376-/* GR05 */
377-#define VGA_GR_MEM_READ_MODE_SHIFT 3
378-#define VGA_GR_MEM_READ_MODE_PLANE 1
379-/* GR06 */
380-#define VGA_GR_MEM_MODE_MASK 0xc
381-#define VGA_GR_MEM_MODE_SHIFT 2
382-#define VGA_GR_MEM_A0000_AFFFF 0
383-#define VGA_GR_MEM_A0000_BFFFF 1
384-#define VGA_GR_MEM_B0000_B7FFF 2
385-#define VGA_GR_MEM_B0000_BFFFF 3
386-
387-#define VGA_DACMASK 0x3c6
388-#define VGA_DACRX 0x3c7
389-#define VGA_DACWX 0x3c8
390-#define VGA_DACDATA 0x3c9
391-
392-#define VGA_CR_INDEX_MDA 0x3b4
393-#define VGA_CR_DATA_MDA 0x3b5
394-#define VGA_CR_INDEX_CGA 0x3d4
395-#define VGA_CR_DATA_CGA 0x3d5
396-
397-#define GFX_OP_USER_INTERRUPT ((0<<29)|(2<<23))
398-#define GFX_OP_BREAKPOINT_INTERRUPT ((0<<29)|(1<<23))
399-#define CMD_REPORT_HEAD (7<<23)
400-#define CMD_STORE_DWORD_IDX ((0x21<<23) | 0x1)
401-#define CMD_OP_BATCH_BUFFER ((0x0<<29)|(0x30<<23)|0x1)
402-
403-#define INST_PARSER_CLIENT 0x00000000
404-#define INST_OP_FLUSH 0x02000000
405-#define INST_FLUSH_MAP_CACHE 0x00000001
406-
407-#define BB1_START_ADDR_MASK (~0x7)
408-#define BB1_PROTECTED (1<<0)
409-#define BB1_UNPROTECTED (0<<0)
410-#define BB2_END_ADDR_MASK (~0x7)
411-
412-/* Framebuffer compression */
413-#define FBC_CFB_BASE 0x03200 /* 4k page aligned */
414-#define FBC_LL_BASE 0x03204 /* 4k page aligned */
415-#define FBC_CONTROL 0x03208
416-#define FBC_CTL_EN (1<<31)
417-#define FBC_CTL_PERIODIC (1<<30)
418-#define FBC_CTL_INTERVAL_SHIFT (16)
419-#define FBC_CTL_UNCOMPRESSIBLE (1<<14)
420-#define FBC_CTL_STRIDE_SHIFT (5)
421-#define FBC_CTL_FENCENO (1<<0)
422-#define FBC_COMMAND 0x0320c
423-#define FBC_CMD_COMPRESS (1<<0)
424-#define FBC_STATUS 0x03210
425-#define FBC_STAT_COMPRESSING (1<<31)
426-#define FBC_STAT_COMPRESSED (1<<30)
427-#define FBC_STAT_MODIFIED (1<<29)
428-#define FBC_STAT_CURRENT_LINE (1<<0)
429-#define FBC_CONTROL2 0x03214
430-#define FBC_CTL_FENCE_DBL (0<<4)
431-#define FBC_CTL_IDLE_IMM (0<<2)
432-#define FBC_CTL_IDLE_FULL (1<<2)
433-#define FBC_CTL_IDLE_LINE (2<<2)
434-#define FBC_CTL_IDLE_DEBUG (3<<2)
435-#define FBC_CTL_CPU_FENCE (1<<1)
436-#define FBC_CTL_PLANEA (0<<0)
437-#define FBC_CTL_PLANEB (1<<0)
438-#define FBC_FENCE_OFF 0x0321b
439-
440-#define FBC_LL_SIZE (1536)
441-#define FBC_LL_PAD (32)
442-
443-/* Interrupt bits:
444- */
445-#define USER_INT_FLAG (1<<1)
446-#define VSYNC_PIPEB_FLAG (1<<5)
447-#define VSYNC_PIPEA_FLAG (1<<7)
448-#define HWB_OOM_FLAG (1<<13) /* binner out of memory */
449-
450-#define I915REG_HWSTAM 0x02098
451-#define I915REG_INT_IDENTITY_R 0x020a4
452-#define I915REG_INT_MASK_R 0x020a8
453-#define I915REG_INT_ENABLE_R 0x020a0
454-
455-#define I915REG_PIPEASTAT 0x70024
456-#define I915REG_PIPEBSTAT 0x71024
457-
458-#define I915_VBLANK_INTERRUPT_ENABLE (1UL<<17)
459-#define I915_VBLANK_CLEAR (1UL<<1)
460-
461-#define SRX_INDEX 0x3c4
462-#define SRX_DATA 0x3c5
463-#define SR01 1
464-#define SR01_SCREEN_OFF (1<<5)
465-
466-#define PPCR 0x61204
467-#define PPCR_ON (1<<0)
468-
469-#define DVOB 0x61140
470-#define DVOB_ON (1<<31)
471-#define DVOC 0x61160
472-#define DVOC_ON (1<<31)
473-#define LVDS 0x61180
474-#define LVDS_ON (1<<31)
475-
476-#define ADPA 0x61100
477-#define ADPA_DPMS_MASK (~(3<<10))
478-#define ADPA_DPMS_ON (0<<10)
479-#define ADPA_DPMS_SUSPEND (1<<10)
480-#define ADPA_DPMS_STANDBY (2<<10)
481-#define ADPA_DPMS_OFF (3<<10)
482-
483-#define NOPID 0x2094
484-#define LP_RING 0x2030
485-#define HP_RING 0x2040
486-/* The binner has its own ring buffer:
487- */
488-#define HWB_RING 0x2400
489-
490-#define RING_TAIL 0x00
491-#define TAIL_ADDR 0x001FFFF8
492-#define RING_HEAD 0x04
493-#define HEAD_WRAP_COUNT 0xFFE00000
494-#define HEAD_WRAP_ONE 0x00200000
495-#define HEAD_ADDR 0x001FFFFC
496-#define RING_START 0x08
497-#define START_ADDR 0x0xFFFFF000
498-#define RING_LEN 0x0C
499-#define RING_NR_PAGES 0x001FF000
500-#define RING_REPORT_MASK 0x00000006
501-#define RING_REPORT_64K 0x00000002
502-#define RING_REPORT_128K 0x00000004
503-#define RING_NO_REPORT 0x00000000
504-#define RING_VALID_MASK 0x00000001
505-#define RING_VALID 0x00000001
506-#define RING_INVALID 0x00000000
507-
508-/* Instruction parser error reg:
509- */
510-#define IPEIR 0x2088
511-
512-/* Scratch pad debug 0 reg:
513- */
514-#define SCPD0 0x209c
515-
516-/* Error status reg:
517- */
518-#define ESR 0x20b8
519-
520-/* Secondary DMA fetch address debug reg:
521- */
522-#define DMA_FADD_S 0x20d4
523-
524-/* Memory Interface Arbitration State
525- */
526-#define MI_ARB_STATE 0x20e4
527-
528-/* Cache mode 0 reg.
529- * - Manipulating render cache behaviour is central
530- * to the concept of zone rendering, tuning this reg can help avoid
531- * unnecessary render cache reads and even writes (for z/stencil)
532- * at beginning and end of scene.
533- *
534- * - To change a bit, write to this reg with a mask bit set and the
535- * bit of interest either set or cleared. EG: (BIT<<16) | BIT to set.
536- */
537-#define Cache_Mode_0 0x2120
538-#define CACHE_MODE_0 0x2120
539-#define CM0_MASK_SHIFT 16
540-#define CM0_IZ_OPT_DISABLE (1<<6)
541-#define CM0_ZR_OPT_DISABLE (1<<5)
542-#define CM0_DEPTH_EVICT_DISABLE (1<<4)
543-#define CM0_COLOR_EVICT_DISABLE (1<<3)
544-#define CM0_DEPTH_WRITE_DISABLE (1<<1)
545-#define CM0_RC_OP_FLUSH_DISABLE (1<<0)
546-
547-
548-/* Graphics flush control. A CPU write flushes the GWB of all writes.
549- * The data is discarded.
550- */
551-#define GFX_FLSH_CNTL 0x2170
552-
553-/* Binner control. Defines the location of the bin pointer list:
554- */
555-#define BINCTL 0x2420
556-#define BC_MASK (1 << 9)
557-
558-/* Binned scene info.
559- */
560-#define BINSCENE 0x2428
561-#define BS_OP_LOAD (1 << 8)
562-#define BS_MASK (1 << 22)
563-
564-/* Bin command parser debug reg:
565- */
566-#define BCPD 0x2480
567-
568-/* Bin memory control debug reg:
569- */
570-#define BMCD 0x2484
571-
572-/* Bin data cache debug reg:
573- */
574-#define BDCD 0x2488
575-
576-/* Binner pointer cache debug reg:
577- */
578-#define BPCD 0x248c
579-
580-/* Binner scratch pad debug reg:
581- */
582-#define BINSKPD 0x24f0
583-
584-/* HWB scratch pad debug reg:
585- */
586-#define HWBSKPD 0x24f4
587-
588-/* Binner memory pool reg:
589- */
590-#define BMP_BUFFER 0x2430
591-#define BMP_PAGE_SIZE_4K (0 << 10)
592-#define BMP_BUFFER_SIZE_SHIFT 1
593-#define BMP_ENABLE (1 << 0)
594-
595-/* Get/put memory from the binner memory pool:
596- */
597-#define BMP_GET 0x2438
598-#define BMP_PUT 0x2440
599-#define BMP_OFFSET_SHIFT 5
600-
601-/* 3D state packets:
602- */
603-#define GFX_OP_RASTER_RULES ((0x3<<29)|(0x7<<24))
604-
605-#define GFX_OP_SCISSOR ((0x3<<29)|(0x1c<<24)|(0x10<<19))
606-#define SC_UPDATE_SCISSOR (0x1<<1)
607-#define SC_ENABLE_MASK (0x1<<0)
608-#define SC_ENABLE (0x1<<0)
609-
610-#define GFX_OP_LOAD_INDIRECT ((0x3<<29)|(0x1d<<24)|(0x7<<16))
611-
612-#define GFX_OP_SCISSOR_INFO ((0x3<<29)|(0x1d<<24)|(0x81<<16)|(0x1))
613-#define SCI_YMIN_MASK (0xffff<<16)
614-#define SCI_XMIN_MASK (0xffff<<0)
615-#define SCI_YMAX_MASK (0xffff<<16)
616-#define SCI_XMAX_MASK (0xffff<<0)
617-
618-#define GFX_OP_SCISSOR_ENABLE ((0x3<<29)|(0x1c<<24)|(0x10<<19))
619-#define GFX_OP_SCISSOR_RECT ((0x3<<29)|(0x1d<<24)|(0x81<<16)|1)
620-#define GFX_OP_COLOR_FACTOR ((0x3<<29)|(0x1d<<24)|(0x1<<16)|0x0)
621-#define GFX_OP_STIPPLE ((0x3<<29)|(0x1d<<24)|(0x83<<16))
622-#define GFX_OP_MAP_INFO ((0x3<<29)|(0x1d<<24)|0x4)
623-#define GFX_OP_DESTBUFFER_VARS ((0x3<<29)|(0x1d<<24)|(0x85<<16)|0x0)
624-#define GFX_OP_DRAWRECT_INFO ((0x3<<29)|(0x1d<<24)|(0x80<<16)|(0x3))
625-
626-#define GFX_OP_DRAWRECT_INFO_I965 ((0x7900<<16)|0x2)
627-
628-#define SRC_COPY_BLT_CMD ((2<<29)|(0x43<<22)|4)
629-#define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6)
630-#define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21)
631-#define XY_SRC_COPY_BLT_WRITE_RGB (1<<20)
632-#define XY_SRC_COPY_BLT_SRC_TILED (1<<15)
633-#define XY_SRC_COPY_BLT_DST_TILED (1<<11)
634-
635-#define MI_BATCH_BUFFER ((0x30<<23)|1)
636-#define MI_BATCH_BUFFER_START (0x31<<23)
637-#define MI_BATCH_BUFFER_END (0xA<<23)
638-#define MI_BATCH_NON_SECURE (1)
639-#define MI_BATCH_NON_SECURE_I965 (1<<8)
640-
641-#define MI_WAIT_FOR_EVENT ((0x3<<23))
642-#define MI_WAIT_FOR_PLANE_B_FLIP (1<<6)
643-#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2)
644-#define MI_WAIT_FOR_PLANE_A_SCANLINES (1<<1)
645-
646-#define MI_LOAD_SCAN_LINES_INCL ((0x12<<23))
647-
648-#define CMD_OP_DISPLAYBUFFER_INFO ((0x0<<29)|(0x14<<23)|2)
649-#define ASYNC_FLIP (1<<22)
650-#define DISPLAY_PLANE_A (0<<20)
651-#define DISPLAY_PLANE_B (1<<20)
652-
653-/* Display regs */
654-#define DSPACNTR 0x70180
655-#define DSPBCNTR 0x71180
656-#define DISPPLANE_SEL_PIPE_MASK (1<<24)
657-
658-/* Define the region of interest for the binner:
659- */
660-#define CMD_OP_BIN_CONTROL ((0x3<<29)|(0x1d<<24)|(0x84<<16)|4)
661-
662-#define CMD_OP_DESTBUFFER_INFO ((0x3<<29)|(0x1d<<24)|(0x8e<<16)|1)
663-
664-#define CMD_MI_FLUSH (0x04 << 23)
665-#define MI_NO_WRITE_FLUSH (1 << 2)
666-#define MI_READ_FLUSH (1 << 0)
667-#define MI_EXE_FLUSH (1 << 1)
668-#define MI_END_SCENE (1 << 4) /* flush binner and incr scene count */
669-#define MI_SCENE_COUNT (1 << 3) /* just increment scene count */
670-
671-#define BREADCRUMB_BITS 31
672-#define BREADCRUMB_MASK ((1U << BREADCRUMB_BITS) - 1)
673-
674-#define READ_BREADCRUMB(dev_priv) (((volatile u32*)(dev_priv->hw_status_page))[5])
675-#define READ_HWSP(dev_priv, reg) (((volatile u32*)(dev_priv->hw_status_page))[reg])
676-
677-#define BLC_PWM_CTL 0x61254
678-#define BACKLIGHT_MODULATION_FREQ_SHIFT (17)
679-
680-#define BLC_PWM_CTL2 0x61250
681 /**
682- * This is the most significant 15 bits of the number of backlight cycles in a
683- * complete cycle of the modulated backlight control.
684+ * Reads a dword out of the status page, which is written to from the command
685+ * queue by automatic updates, MI_REPORT_HEAD, MI_STORE_DATA_INDEX, or
686+ * MI_STORE_DATA_IMM.
687 *
688- * The actual value is this field multiplied by two.
689- */
690-#define BACKLIGHT_MODULATION_FREQ_MASK (0x7fff << 17)
691-#define BLM_LEGACY_MODE (1 << 16)
692-/**
693- * This is the number of cycles out of the backlight modulation cycle for which
694- * the backlight is on.
695+ * The following dwords have a reserved meaning:
696+ * 0: ISR copy, updated when an ISR bit not set in the HWSTAM changes.
697+ * 4: ring 0 head pointer
698+ * 5: ring 1 head pointer (915-class)
699+ * 6: ring 2 head pointer (915-class)
700 *
701- * This field must be no greater than the number of cycles in the complete
702- * backlight modulation cycle.
703- */
704-#define BACKLIGHT_DUTY_CYCLE_SHIFT (0)
705-#define BACKLIGHT_DUTY_CYCLE_MASK (0xffff)
706-
707-#define I915_GCFGC 0xf0
708-#define I915_LOW_FREQUENCY_ENABLE (1 << 7)
709-#define I915_DISPLAY_CLOCK_190_200_MHZ (0 << 4)
710-#define I915_DISPLAY_CLOCK_333_MHZ (4 << 4)
711-#define I915_DISPLAY_CLOCK_MASK (7 << 4)
712-
713-#define I855_HPLLCC 0xc0
714-#define I855_CLOCK_CONTROL_MASK (3 << 0)
715-#define I855_CLOCK_133_200 (0 << 0)
716-#define I855_CLOCK_100_200 (1 << 0)
717-#define I855_CLOCK_100_133 (2 << 0)
718-#define I855_CLOCK_166_250 (3 << 0)
719-
720-/* p317, 319
721+ * The area from dword 0x10 to 0x3ff is available for driver usage.
722 */
723-#define VCLK2_VCO_M 0x6008 /* treat as 16 bit? (includes msbs) */
724-#define VCLK2_VCO_N 0x600a
725-#define VCLK2_VCO_DIV_SEL 0x6012
726-
727-#define VCLK_DIVISOR_VGA0 0x6000
728-#define VCLK_DIVISOR_VGA1 0x6004
729-#define VCLK_POST_DIV 0x6010
730-/** Selects a post divisor of 4 instead of 2. */
731-# define VGA1_PD_P2_DIV_4 (1 << 15)
732-/** Overrides the p2 post divisor field */
733-# define VGA1_PD_P1_DIV_2 (1 << 13)
734-# define VGA1_PD_P1_SHIFT 8
735-/** P1 value is 2 greater than this field */
736-# define VGA1_PD_P1_MASK (0x1f << 8)
737-/** Selects a post divisor of 4 instead of 2. */
738-# define VGA0_PD_P2_DIV_4 (1 << 7)
739-/** Overrides the p2 post divisor field */
740-# define VGA0_PD_P1_DIV_2 (1 << 5)
741-# define VGA0_PD_P1_SHIFT 0
742-/** P1 value is 2 greater than this field */
743-# define VGA0_PD_P1_MASK (0x1f << 0)
744-
745-/* PCI D state control register */
746-#define D_STATE 0x6104
747-#define DSPCLK_GATE_D 0x6200
748-
749-/* I830 CRTC registers */
750-#define HTOTAL_A 0x60000
751-#define HBLANK_A 0x60004
752-#define HSYNC_A 0x60008
753-#define VTOTAL_A 0x6000c
754-#define VBLANK_A 0x60010
755-#define VSYNC_A 0x60014
756-#define PIPEASRC 0x6001c
757-#define BCLRPAT_A 0x60020
758-#define VSYNCSHIFT_A 0x60028
759-
760-#define HTOTAL_B 0x61000
761-#define HBLANK_B 0x61004
762-#define HSYNC_B 0x61008
763-#define VTOTAL_B 0x6100c
764-#define VBLANK_B 0x61010
765-#define VSYNC_B 0x61014
766-#define PIPEBSRC 0x6101c
767-#define BCLRPAT_B 0x61020
768-#define VSYNCSHIFT_B 0x61028
769-
770-#define PP_STATUS 0x61200
771-# define PP_ON (1 << 31)
772-/**
773- * Indicates that all dependencies of the panel are on:
774- *
775- * - PLL enabled
776- * - pipe enabled
777- * - LVDS/DVOB/DVOC on
778- */
779-# define PP_READY (1 << 30)
780-# define PP_SEQUENCE_NONE (0 << 28)
781-# define PP_SEQUENCE_ON (1 << 28)
782-# define PP_SEQUENCE_OFF (2 << 28)
783-# define PP_SEQUENCE_MASK 0x30000000
784-#define PP_CONTROL 0x61204
785-# define POWER_TARGET_ON (1 << 0)
786-
787-#define LVDSPP_ON 0x61208
788-#define LVDSPP_OFF 0x6120c
789-#define PP_CYCLE 0x61210
790-
791-#define PFIT_CONTROL 0x61230
792-# define PFIT_ENABLE (1 << 31)
793-# define PFIT_PIPE_MASK (3 << 29)
794-# define PFIT_PIPE_SHIFT 29
795-# define VERT_INTERP_DISABLE (0 << 10)
796-# define VERT_INTERP_BILINEAR (1 << 10)
797-# define VERT_INTERP_MASK (3 << 10)
798-# define VERT_AUTO_SCALE (1 << 9)
799-# define HORIZ_INTERP_DISABLE (0 << 6)
800-# define HORIZ_INTERP_BILINEAR (1 << 6)
801-# define HORIZ_INTERP_MASK (3 << 6)
802-# define HORIZ_AUTO_SCALE (1 << 5)
803-# define PANEL_8TO6_DITHER_ENABLE (1 << 3)
804-
805-#define PFIT_PGM_RATIOS 0x61234
806-# define PFIT_VERT_SCALE_MASK 0xfff00000
807-# define PFIT_HORIZ_SCALE_MASK 0x0000fff0
808-
809-#define PFIT_AUTO_RATIOS 0x61238
810-
811-
812-#define DPLL_A 0x06014
813-#define DPLL_B 0x06018
814-# define DPLL_VCO_ENABLE (1 << 31)
815-# define DPLL_DVO_HIGH_SPEED (1 << 30)
816-# define DPLL_SYNCLOCK_ENABLE (1 << 29)
817-# define DPLL_VGA_MODE_DIS (1 << 28)
818-# define DPLLB_MODE_DAC_SERIAL (1 << 26) /* i915 */
819-# define DPLLB_MODE_LVDS (2 << 26) /* i915 */
820-# define DPLL_MODE_MASK (3 << 26)
821-# define DPLL_DAC_SERIAL_P2_CLOCK_DIV_10 (0 << 24) /* i915 */
822-# define DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 (1 << 24) /* i915 */
823-# define DPLLB_LVDS_P2_CLOCK_DIV_14 (0 << 24) /* i915 */
824-# define DPLLB_LVDS_P2_CLOCK_DIV_7 (1 << 24) /* i915 */
825-# define DPLL_P2_CLOCK_DIV_MASK 0x03000000 /* i915 */
826-# define DPLL_FPA01_P1_POST_DIV_MASK 0x00ff0000 /* i915 */
827-/**
828- * The i830 generation, in DAC/serial mode, defines p1 as two plus this
829- * bitfield, or just 2 if PLL_P1_DIVIDE_BY_TWO is set.
830- */
831-# define DPLL_FPA01_P1_POST_DIV_MASK_I830 0x001f0000
832-/**
833- * The i830 generation, in LVDS mode, defines P1 as the bit number set within
834- * this field (only one bit may be set).
835- */
836-# define DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS 0x003f0000
837-# define DPLL_FPA01_P1_POST_DIV_SHIFT 16
838-# define PLL_P2_DIVIDE_BY_4 (1 << 23) /* i830, required in DVO non-gang */
839-# define PLL_P1_DIVIDE_BY_TWO (1 << 21) /* i830 */
840-# define PLL_REF_INPUT_DREFCLK (0 << 13)
841-# define PLL_REF_INPUT_TVCLKINA (1 << 13) /* i830 */
842-# define PLL_REF_INPUT_TVCLKINBC (2 << 13) /* SDVO TVCLKIN */
843-# define PLLB_REF_INPUT_SPREADSPECTRUMIN (3 << 13)
844-# define PLL_REF_INPUT_MASK (3 << 13)
845-# define PLL_LOAD_PULSE_PHASE_SHIFT 9
846-/*
847- * Parallel to Serial Load Pulse phase selection.
848- * Selects the phase for the 10X DPLL clock for the PCIe
849- * digital display port. The range is 4 to 13; 10 or more
850- * is just a flip delay. The default is 6
851- */
852-# define PLL_LOAD_PULSE_PHASE_MASK (0xf << PLL_LOAD_PULSE_PHASE_SHIFT)
853-# define DISPLAY_RATE_SELECT_FPA1 (1 << 8)
854-
855-/**
856- * SDVO multiplier for 945G/GM. Not used on 965.
857- *
858- * \sa DPLL_MD_UDI_MULTIPLIER_MASK
859- */
860-# define SDVO_MULTIPLIER_MASK 0x000000ff
861-# define SDVO_MULTIPLIER_SHIFT_HIRES 4
862-# define SDVO_MULTIPLIER_SHIFT_VGA 0
863-
864-/** @defgroup DPLL_MD
865- * @{
866- */
867-/** Pipe A SDVO/UDI clock multiplier/divider register for G965. */
868-#define DPLL_A_MD 0x0601c
869-/** Pipe B SDVO/UDI clock multiplier/divider register for G965. */
870-#define DPLL_B_MD 0x06020
871-/**
872- * UDI pixel divider, controlling how many pixels are stuffed into a packet.
873- *
874- * Value is pixels minus 1. Must be set to 1 pixel for SDVO.
875- */
876-# define DPLL_MD_UDI_DIVIDER_MASK 0x3f000000
877-# define DPLL_MD_UDI_DIVIDER_SHIFT 24
878-/** UDI pixel divider for VGA, same as DPLL_MD_UDI_DIVIDER_MASK. */
879-# define DPLL_MD_VGA_UDI_DIVIDER_MASK 0x003f0000
880-# define DPLL_MD_VGA_UDI_DIVIDER_SHIFT 16
881-/**
882- * SDVO/UDI pixel multiplier.
883- *
884- * SDVO requires that the bus clock rate be between 1 and 2 Ghz, and the bus
885- * clock rate is 10 times the DPLL clock. At low resolution/refresh rate
886- * modes, the bus rate would be below the limits, so SDVO allows for stuffing
887- * dummy bytes in the datastream at an increased clock rate, with both sides of
888- * the link knowing how many bytes are fill.
889- *
890- * So, for a mode with a dotclock of 65Mhz, we would want to double the clock
891- * rate to 130Mhz to get a bus rate of 1.30Ghz. The DPLL clock rate would be
892- * set to 130Mhz, and the SDVO multiplier set to 2x in this register and
893- * through an SDVO command.
894- *
895- * This register field has values of multiplication factor minus 1, with
896- * a maximum multiplier of 5 for SDVO.
897- */
898-# define DPLL_MD_UDI_MULTIPLIER_MASK 0x00003f00
899-# define DPLL_MD_UDI_MULTIPLIER_SHIFT 8
900-/** SDVO/UDI pixel multiplier for VGA, same as DPLL_MD_UDI_MULTIPLIER_MASK.
901- * This best be set to the default value (3) or the CRT won't work. No,
902- * I don't entirely understand what this does...
903- */
904-# define DPLL_MD_VGA_UDI_MULTIPLIER_MASK 0x0000003f
905-# define DPLL_MD_VGA_UDI_MULTIPLIER_SHIFT 0
906-/** @} */
907-
908-#define DPLL_TEST 0x606c
909-# define DPLLB_TEST_SDVO_DIV_1 (0 << 22)
910-# define DPLLB_TEST_SDVO_DIV_2 (1 << 22)
911-# define DPLLB_TEST_SDVO_DIV_4 (2 << 22)
912-# define DPLLB_TEST_SDVO_DIV_MASK (3 << 22)
913-# define DPLLB_TEST_N_BYPASS (1 << 19)
914-# define DPLLB_TEST_M_BYPASS (1 << 18)
915-# define DPLLB_INPUT_BUFFER_ENABLE (1 << 16)
916-# define DPLLA_TEST_N_BYPASS (1 << 3)
917-# define DPLLA_TEST_M_BYPASS (1 << 2)
918-# define DPLLA_INPUT_BUFFER_ENABLE (1 << 0)
919-
920-#define ADPA 0x61100
921-#define ADPA_DAC_ENABLE (1<<31)
922-#define ADPA_DAC_DISABLE 0
923-#define ADPA_PIPE_SELECT_MASK (1<<30)
924-#define ADPA_PIPE_A_SELECT 0
925-#define ADPA_PIPE_B_SELECT (1<<30)
926-#define ADPA_USE_VGA_HVPOLARITY (1<<15)
927-#define ADPA_SETS_HVPOLARITY 0
928-#define ADPA_VSYNC_CNTL_DISABLE (1<<11)
929-#define ADPA_VSYNC_CNTL_ENABLE 0
930-#define ADPA_HSYNC_CNTL_DISABLE (1<<10)
931-#define ADPA_HSYNC_CNTL_ENABLE 0
932-#define ADPA_VSYNC_ACTIVE_HIGH (1<<4)
933-#define ADPA_VSYNC_ACTIVE_LOW 0
934-#define ADPA_HSYNC_ACTIVE_HIGH (1<<3)
935-#define ADPA_HSYNC_ACTIVE_LOW 0
936-
937-#define FPA0 0x06040
938-#define FPA1 0x06044
939-#define FPB0 0x06048
940-#define FPB1 0x0604c
941-# define FP_N_DIV_MASK 0x003f0000
942-# define FP_N_DIV_SHIFT 16
943-# define FP_M1_DIV_MASK 0x00003f00
944-# define FP_M1_DIV_SHIFT 8
945-# define FP_M2_DIV_MASK 0x0000003f
946-# define FP_M2_DIV_SHIFT 0
947-
948-
949-#define PORT_HOTPLUG_EN 0x61110
950-# define SDVOB_HOTPLUG_INT_EN (1 << 26)
951-# define SDVOC_HOTPLUG_INT_EN (1 << 25)
952-# define TV_HOTPLUG_INT_EN (1 << 18)
953-# define CRT_HOTPLUG_INT_EN (1 << 9)
954-# define CRT_HOTPLUG_FORCE_DETECT (1 << 3)
955-
956-#define PORT_HOTPLUG_STAT 0x61114
957-# define CRT_HOTPLUG_INT_STATUS (1 << 11)
958-# define TV_HOTPLUG_INT_STATUS (1 << 10)
959-# define CRT_HOTPLUG_MONITOR_MASK (3 << 8)
960-# define CRT_HOTPLUG_MONITOR_COLOR (3 << 8)
961-# define CRT_HOTPLUG_MONITOR_MONO (2 << 8)
962-# define CRT_HOTPLUG_MONITOR_NONE (0 << 8)
963-# define SDVOC_HOTPLUG_INT_STATUS (1 << 7)
964-# define SDVOB_HOTPLUG_INT_STATUS (1 << 6)
965-
966-#define SDVOB 0x61140
967-#define SDVOC 0x61160
968-#define SDVO_ENABLE (1 << 31)
969-#define SDVO_PIPE_B_SELECT (1 << 30)
970-#define SDVO_STALL_SELECT (1 << 29)
971-#define SDVO_INTERRUPT_ENABLE (1 << 26)
972-/**
973- * 915G/GM SDVO pixel multiplier.
974- *
975- * Programmed value is multiplier - 1, up to 5x.
976- *
977- * \sa DPLL_MD_UDI_MULTIPLIER_MASK
978- */
979-#define SDVO_PORT_MULTIPLY_MASK (7 << 23)
980-#define SDVO_PORT_MULTIPLY_SHIFT 23
981-#define SDVO_PHASE_SELECT_MASK (15 << 19)
982-#define SDVO_PHASE_SELECT_DEFAULT (6 << 19)
983-#define SDVO_CLOCK_OUTPUT_INVERT (1 << 18)
984-#define SDVOC_GANG_MODE (1 << 16)
985-#define SDVO_BORDER_ENABLE (1 << 7)
986-#define SDVOB_PCIE_CONCURRENCY (1 << 3)
987-#define SDVO_DETECTED (1 << 2)
988-/* Bits to be preserved when writing */
989-#define SDVOB_PRESERVE_MASK ((1 << 17) | (1 << 16) | (1 << 14))
990-#define SDVOC_PRESERVE_MASK (1 << 17)
991-
992-/** @defgroup LVDS
993- * @{
994- */
995-/**
996- * This register controls the LVDS output enable, pipe selection, and data
997- * format selection.
998- *
999- * All of the clock/data pairs are force powered down by power sequencing.
1000- */
1001-#define LVDS 0x61180
1002-/**
1003- * Enables the LVDS port. This bit must be set before DPLLs are enabled, as
1004- * the DPLL semantics change when the LVDS is assigned to that pipe.
1005- */
1006-# define LVDS_PORT_EN (1 << 31)
1007-/** Selects pipe B for LVDS data. Must be set on pre-965. */
1008-# define LVDS_PIPEB_SELECT (1 << 30)
1009-
1010-/**
1011- * Enables the A0-A2 data pairs and CLKA, containing 18 bits of color data per
1012- * pixel.
1013- */
1014-# define LVDS_A0A2_CLKA_POWER_MASK (3 << 8)
1015-# define LVDS_A0A2_CLKA_POWER_DOWN (0 << 8)
1016-# define LVDS_A0A2_CLKA_POWER_UP (3 << 8)
1017-/**
1018- * Controls the A3 data pair, which contains the additional LSBs for 24 bit
1019- * mode. Only enabled if LVDS_A0A2_CLKA_POWER_UP also indicates it should be
1020- * on.
1021- */
1022-# define LVDS_A3_POWER_MASK (3 << 6)
1023-# define LVDS_A3_POWER_DOWN (0 << 6)
1024-# define LVDS_A3_POWER_UP (3 << 6)
1025-/**
1026- * Controls the CLKB pair. This should only be set when LVDS_B0B3_POWER_UP
1027- * is set.
1028- */
1029-# define LVDS_CLKB_POWER_MASK (3 << 4)
1030-# define LVDS_CLKB_POWER_DOWN (0 << 4)
1031-# define LVDS_CLKB_POWER_UP (3 << 4)
1032-
1033-/**
1034- * Controls the B0-B3 data pairs. This must be set to match the DPLL p2
1035- * setting for whether we are in dual-channel mode. The B3 pair will
1036- * additionally only be powered up when LVDS_A3_POWER_UP is set.
1037- */
1038-# define LVDS_B0B3_POWER_MASK (3 << 2)
1039-# define LVDS_B0B3_POWER_DOWN (0 << 2)
1040-# define LVDS_B0B3_POWER_UP (3 << 2)
1041-
1042-#define PIPEACONF 0x70008
1043-#define PIPEACONF_ENABLE (1<<31)
1044-#define PIPEACONF_DISABLE 0
1045-#define PIPEACONF_DOUBLE_WIDE (1<<30)
1046-#define I965_PIPECONF_ACTIVE (1<<30)
1047-#define PIPEACONF_SINGLE_WIDE 0
1048-#define PIPEACONF_PIPE_UNLOCKED 0
1049-#define PIPEACONF_PIPE_LOCKED (1<<25)
1050-#define PIPEACONF_PALETTE 0
1051-#define PIPEACONF_GAMMA (1<<24)
1052-#define PIPECONF_FORCE_BORDER (1<<25)
1053-#define PIPECONF_PROGRESSIVE (0 << 21)
1054-#define PIPECONF_INTERLACE_W_FIELD_INDICATION (6 << 21)
1055-#define PIPECONF_INTERLACE_FIELD_0_ONLY (7 << 21)
1056-
1057-#define DSPARB 0x70030
1058-#define DSPARB_CSTART_MASK (0x7f << 7)
1059-#define DSPARB_CSTART_SHIFT 7
1060-#define DSPARB_BSTART_MASK (0x7f)
1061-#define DSPARB_BSTART_SHIFT 0
1062-
1063-#define PIPEBCONF 0x71008
1064-#define PIPEBCONF_ENABLE (1<<31)
1065-#define PIPEBCONF_DISABLE 0
1066-#define PIPEBCONF_DOUBLE_WIDE (1<<30)
1067-#define PIPEBCONF_DISABLE 0
1068-#define PIPEBCONF_GAMMA (1<<24)
1069-#define PIPEBCONF_PALETTE 0
1070-
1071-#define PIPEBGCMAXRED 0x71010
1072-#define PIPEBGCMAXGREEN 0x71014
1073-#define PIPEBGCMAXBLUE 0x71018
1074-#define PIPEBSTAT 0x71024
1075-#define PIPEBFRAMEHIGH 0x71040
1076-#define PIPEBFRAMEPIXEL 0x71044
1077-
1078-#define DSPACNTR 0x70180
1079-#define DSPBCNTR 0x71180
1080-#define DISPLAY_PLANE_ENABLE (1<<31)
1081-#define DISPLAY_PLANE_DISABLE 0
1082-#define DISPPLANE_GAMMA_ENABLE (1<<30)
1083-#define DISPPLANE_GAMMA_DISABLE 0
1084-#define DISPPLANE_PIXFORMAT_MASK (0xf<<26)
1085-#define DISPPLANE_8BPP (0x2<<26)
1086-#define DISPPLANE_15_16BPP (0x4<<26)
1087-#define DISPPLANE_16BPP (0x5<<26)
1088-#define DISPPLANE_32BPP_NO_ALPHA (0x6<<26)
1089-#define DISPPLANE_32BPP (0x7<<26)
1090-#define DISPPLANE_STEREO_ENABLE (1<<25)
1091-#define DISPPLANE_STEREO_DISABLE 0
1092-#define DISPPLANE_SEL_PIPE_MASK (1<<24)
1093-#define DISPPLANE_SEL_PIPE_A 0
1094-#define DISPPLANE_SEL_PIPE_B (1<<24)
1095-#define DISPPLANE_SRC_KEY_ENABLE (1<<22)
1096-#define DISPPLANE_SRC_KEY_DISABLE 0
1097-#define DISPPLANE_LINE_DOUBLE (1<<20)
1098-#define DISPPLANE_NO_LINE_DOUBLE 0
1099-#define DISPPLANE_STEREO_POLARITY_FIRST 0
1100-#define DISPPLANE_STEREO_POLARITY_SECOND (1<<18)
1101-/* plane B only */
1102-#define DISPPLANE_ALPHA_TRANS_ENABLE (1<<15)
1103-#define DISPPLANE_ALPHA_TRANS_DISABLE 0
1104-#define DISPPLANE_SPRITE_ABOVE_DISPLAYA 0
1105-#define DISPPLANE_SPRITE_ABOVE_OVERLAY (1)
1106-
1107-#define DSPABASE 0x70184
1108-#define DSPASTRIDE 0x70188
1109-
1110-#define DSPBBASE 0x71184
1111-#define DSPBADDR DSPBBASE
1112-#define DSPBSTRIDE 0x71188
1113-
1114-#define DSPAKEYVAL 0x70194
1115-#define DSPAKEYMASK 0x70198
1116-
1117-#define DSPAPOS 0x7018C /* reserved */
1118-#define DSPASIZE 0x70190
1119-#define DSPBPOS 0x7118C
1120-#define DSPBSIZE 0x71190
1121-
1122-#define DSPASURF 0x7019C
1123-#define DSPATILEOFF 0x701A4
1124-
1125-#define DSPBSURF 0x7119C
1126-#define DSPBTILEOFF 0x711A4
1127-
1128-#define VGACNTRL 0x71400
1129-# define VGA_DISP_DISABLE (1 << 31)
1130-# define VGA_2X_MODE (1 << 30)
1131-# define VGA_PIPE_B_SELECT (1 << 29)
1132-
1133-/*
1134- * Some BIOS scratch area registers. The 845 (and 830?) store the amount
1135- * of video memory available to the BIOS in SWF1.
1136- */
1137-
1138-#define SWF0 0x71410
1139-
1140-/*
1141- * 855 scratch registers.
1142- */
1143-#define SWF10 0x70410
1144-
1145-#define SWF30 0x72414
1146-
1147-/*
1148- * Overlay registers. These are overlay registers accessed via MMIO.
1149- * Those loaded via the overlay register page are defined in i830_video.c.
1150- */
1151-#define OVADD 0x30000
1152-
1153-#define DOVSTA 0x30008
1154-#define OC_BUF (0x3<<20)
1155+#define READ_HWSP(dev_priv, reg) (((volatile u32*)(dev_priv->hw_status_page))[reg])
1156+#define READ_BREADCRUMB(dev_priv) READ_HWSP(dev_priv, 5)
1157
1158-#define OGAMC5 0x30010
1159-#define OGAMC4 0x30014
1160-#define OGAMC3 0x30018
1161-#define OGAMC2 0x3001c
1162-#define OGAMC1 0x30020
1163-#define OGAMC0 0x30024
1164-/*
1165- * Palette registers
1166- */
1167-#define PALETTE_A 0x0a000
1168-#define PALETTE_B 0x0a800
1169+extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
1170
1171 #define IS_I830(dev) ((dev)->pci_device == 0x3577)
1172 #define IS_845G(dev) ((dev)->pci_device == 0x2562)
1173diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
1174index df03611..4a2de78 100644
1175--- a/drivers/gpu/drm/i915/i915_irq.c
1176+++ b/drivers/gpu/drm/i915/i915_irq.c
1177@@ -31,10 +31,6 @@
1178 #include "i915_drm.h"
1179 #include "i915_drv.h"
1180
1181-#define USER_INT_FLAG (1<<1)
1182-#define VSYNC_PIPEB_FLAG (1<<5)
1183-#define VSYNC_PIPEA_FLAG (1<<7)
1184-
1185 #define MAX_NOPID ((u32)~0)
1186
1187 /**
1188@@ -236,40 +232,43 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
1189 u16 temp;
1190 u32 pipea_stats, pipeb_stats;
1191
1192- pipea_stats = I915_READ(I915REG_PIPEASTAT);
1193- pipeb_stats = I915_READ(I915REG_PIPEBSTAT);
1194+ pipea_stats = I915_READ(PIPEASTAT);
1195+ pipeb_stats = I915_READ(PIPEBSTAT);
1196
1197- temp = I915_READ16(I915REG_INT_IDENTITY_R);
1198+ temp = I915_READ16(IIR);
1199
1200- temp &= (USER_INT_FLAG | VSYNC_PIPEA_FLAG | VSYNC_PIPEB_FLAG);
1201+ temp &= (I915_USER_INTERRUPT |
1202+ I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT |
1203+ I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT);
1204
1205 DRM_DEBUG("%s flag=%08x\n", __FUNCTION__, temp);
1206
1207 if (temp == 0)
1208 return IRQ_NONE;
1209
1210- I915_WRITE16(I915REG_INT_IDENTITY_R, temp);
1211- (void) I915_READ16(I915REG_INT_IDENTITY_R);
1212+ I915_WRITE16(IIR, temp);
1213+ (void) I915_READ16(IIR);
1214 DRM_READMEMORYBARRIER();
1215
1216 dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
1217
1218- if (temp & USER_INT_FLAG)
1219+ if (temp & I915_USER_INTERRUPT)
1220 DRM_WAKEUP(&dev_priv->irq_queue);
1221
1222- if (temp & (VSYNC_PIPEA_FLAG | VSYNC_PIPEB_FLAG)) {
1223+ if (temp & (I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT |
1224+ I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT)) {
1225 int vblank_pipe = dev_priv->vblank_pipe;
1226
1227 if ((vblank_pipe &
1228 (DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B))
1229 == (DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B)) {
1230- if (temp & VSYNC_PIPEA_FLAG)
1231+ if (temp & I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT)
1232 atomic_inc(&dev->vbl_received);
1233- if (temp & VSYNC_PIPEB_FLAG)
1234+ if (temp & I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT)
1235 atomic_inc(&dev->vbl_received2);
1236- } else if (((temp & VSYNC_PIPEA_FLAG) &&
1237+ } else if (((temp & I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT) &&
1238 (vblank_pipe & DRM_I915_VBLANK_PIPE_A)) ||
1239- ((temp & VSYNC_PIPEB_FLAG) &&
1240+ ((temp & I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT) &&
1241 (vblank_pipe & DRM_I915_VBLANK_PIPE_B)))
1242 atomic_inc(&dev->vbl_received);
1243
1244@@ -278,12 +277,12 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
1245
1246 if (dev_priv->swaps_pending > 0)
1247 drm_locked_tasklet(dev, i915_vblank_tasklet);
1248- I915_WRITE(I915REG_PIPEASTAT,
1249+ I915_WRITE(PIPEASTAT,
1250 pipea_stats|I915_VBLANK_INTERRUPT_ENABLE|
1251- I915_VBLANK_CLEAR);
1252- I915_WRITE(I915REG_PIPEBSTAT,
1253+ PIPE_VBLANK_INTERRUPT_STATUS);
1254+ I915_WRITE(PIPEBSTAT,
1255 pipeb_stats|I915_VBLANK_INTERRUPT_ENABLE|
1256- I915_VBLANK_CLEAR);
1257+ PIPE_VBLANK_INTERRUPT_STATUS);
1258 }
1259
1260 return IRQ_HANDLED;
1261@@ -304,12 +303,12 @@ static int i915_emit_irq(struct drm_device * dev)
1262 dev_priv->sarea_priv->last_enqueue = dev_priv->counter = 1;
1263
1264 BEGIN_LP_RING(6);
1265- OUT_RING(CMD_STORE_DWORD_IDX);
1266- OUT_RING(20);
1267+ OUT_RING(MI_STORE_DWORD_INDEX);
1268+ OUT_RING(5 << MI_STORE_DWORD_INDEX_SHIFT);
1269 OUT_RING(dev_priv->counter);
1270 OUT_RING(0);
1271 OUT_RING(0);
1272- OUT_RING(GFX_OP_USER_INTERRUPT);
1273+ OUT_RING(MI_USER_INTERRUPT);
1274 ADVANCE_LP_RING();
1275
1276 return dev_priv->counter;
1277@@ -421,11 +420,11 @@ static void i915_enable_interrupt (struct drm_device *dev)
1278
1279 flag = 0;
1280 if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_A)
1281- flag |= VSYNC_PIPEA_FLAG;
1282+ flag |= I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT;
1283 if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_B)
1284- flag |= VSYNC_PIPEB_FLAG;
1285+ flag |= I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
1286
1287- I915_WRITE16(I915REG_INT_ENABLE_R, USER_INT_FLAG | flag);
1288+ I915_WRITE16(IER, I915_USER_INTERRUPT | flag);
1289 }
1290
1291 /* Set the vblank monitor pipe
1292@@ -465,11 +464,11 @@ int i915_vblank_pipe_get(struct drm_device *dev, void *data,
1293 return -EINVAL;
1294 }
1295
1296- flag = I915_READ(I915REG_INT_ENABLE_R);
1297+ flag = I915_READ(IER);
1298 pipe->pipe = 0;
1299- if (flag & VSYNC_PIPEA_FLAG)
1300+ if (flag & I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT)
1301 pipe->pipe |= DRM_I915_VBLANK_PIPE_A;
1302- if (flag & VSYNC_PIPEB_FLAG)
1303+ if (flag & I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT)
1304 pipe->pipe |= DRM_I915_VBLANK_PIPE_B;
1305
1306 return 0;
1307@@ -587,9 +586,9 @@ void i915_driver_irq_preinstall(struct drm_device * dev)
1308 {
1309 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
1310
1311- I915_WRITE16(I915REG_HWSTAM, 0xfffe);
1312- I915_WRITE16(I915REG_INT_MASK_R, 0x0);
1313- I915_WRITE16(I915REG_INT_ENABLE_R, 0x0);
1314+ I915_WRITE16(HWSTAM, 0xfffe);
1315+ I915_WRITE16(IMR, 0x0);
1316+ I915_WRITE16(IER, 0x0);
1317 }
1318
1319 void i915_driver_irq_postinstall(struct drm_device * dev)
1320@@ -614,10 +613,10 @@ void i915_driver_irq_uninstall(struct drm_device * dev)
1321 if (!dev_priv)
1322 return;
1323
1324- I915_WRITE16(I915REG_HWSTAM, 0xffff);
1325- I915_WRITE16(I915REG_INT_MASK_R, 0xffff);
1326- I915_WRITE16(I915REG_INT_ENABLE_R, 0x0);
1327+ I915_WRITE16(HWSTAM, 0xffff);
1328+ I915_WRITE16(IMR, 0xffff);
1329+ I915_WRITE16(IER, 0x0);
1330
1331- temp = I915_READ16(I915REG_INT_IDENTITY_R);
1332- I915_WRITE16(I915REG_INT_IDENTITY_R, temp);
1333+ temp = I915_READ16(IIR);
1334+ I915_WRITE16(IIR, temp);
1335 }
1336diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
1337new file mode 100644
1338index 0000000..477c64e
1339--- /dev/null
1340+++ b/drivers/gpu/drm/i915/i915_reg.h
1341@@ -0,0 +1,1405 @@
1342+/* Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
1343+ * All Rights Reserved.
1344+ *
1345+ * Permission is hereby granted, free of charge, to any person obtaining a
1346+ * copy of this software and associated documentation files (the
1347+ * "Software"), to deal in the Software without restriction, including
1348+ * without limitation the rights to use, copy, modify, merge, publish,
1349+ * distribute, sub license, and/or sell copies of the Software, and to
1350+ * permit persons to whom the Software is furnished to do so, subject to
1351+ * the following conditions:
1352+ *
1353+ * The above copyright notice and this permission notice (including the
1354+ * next paragraph) shall be included in all copies or substantial portions
1355+ * of the Software.
1356+ *
1357+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
1358+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
1359+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
1360+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
1361+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
1362+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
1363+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1364+ */
1365+
1366+#ifndef _I915_REG_H_
1367+#define _I915_REG_H_
1368+
1369+/* MCH MMIO space */
1370+/** 915-945 and GM965 MCH register controlling DRAM channel access */
1371+#define DCC 0x200
1372+#define DCC_ADDRESSING_MODE_SINGLE_CHANNEL (0 << 0)
1373+#define DCC_ADDRESSING_MODE_DUAL_CHANNEL_ASYMMETRIC (1 << 0)
1374+#define DCC_ADDRESSING_MODE_DUAL_CHANNEL_INTERLEAVED (2 << 0)
1375+#define DCC_ADDRESSING_MODE_MASK (3 << 0)
1376+#define DCC_CHANNEL_XOR_DISABLE (1 << 10)
1377+
1378+/** 965 MCH register controlling DRAM channel configuration */
1379+#define CHDECMISC 0x111
1380+#define CHDECMISC_FLEXMEMORY (1 << 1)
1381+
1382+/*
1383+ * The Bridge device's PCI config space has information about the
1384+ * fb aperture size and the amount of pre-reserved memory.
1385+ */
1386+#define INTEL_GMCH_CTRL 0x52
1387+#define INTEL_GMCH_ENABLED 0x4
1388+#define INTEL_GMCH_MEM_MASK 0x1
1389+#define INTEL_GMCH_MEM_64M 0x1
1390+#define INTEL_GMCH_MEM_128M 0
1391+
1392+#define INTEL_855_GMCH_GMS_MASK (0x7 << 4)
1393+#define INTEL_855_GMCH_GMS_DISABLED (0x0 << 4)
1394+#define INTEL_855_GMCH_GMS_STOLEN_1M (0x1 << 4)
1395+#define INTEL_855_GMCH_GMS_STOLEN_4M (0x2 << 4)
1396+#define INTEL_855_GMCH_GMS_STOLEN_8M (0x3 << 4)
1397+#define INTEL_855_GMCH_GMS_STOLEN_16M (0x4 << 4)
1398+#define INTEL_855_GMCH_GMS_STOLEN_32M (0x5 << 4)
1399+
1400+#define INTEL_915G_GMCH_GMS_STOLEN_48M (0x6 << 4)
1401+#define INTEL_915G_GMCH_GMS_STOLEN_64M (0x7 << 4)
1402+
1403+/* PCI config space */
1404+
1405+#define HPLLCC 0xc0 /* 855 only */
1406+#define GC_CLOCK_CONTROL_MASK (3 << 0)
1407+#define GC_CLOCK_133_200 (0 << 0)
1408+#define GC_CLOCK_100_200 (1 << 0)
1409+#define GC_CLOCK_100_133 (2 << 0)
1410+#define GC_CLOCK_166_250 (3 << 0)
1411+#define GCFGC 0xf0 /* 915+ only */
1412+#define GC_LOW_FREQUENCY_ENABLE (1 << 7)
1413+#define GC_DISPLAY_CLOCK_190_200_MHZ (0 << 4)
1414+#define GC_DISPLAY_CLOCK_333_MHZ (4 << 4)
1415+#define GC_DISPLAY_CLOCK_MASK (7 << 4)
1416+#define LBB 0xf4
1417+
1418+/* VGA stuff */
1419+
1420+#define VGA_ST01_MDA 0x3ba
1421+#define VGA_ST01_CGA 0x3da
1422+
1423+#define VGA_MSR_WRITE 0x3c2
1424+#define VGA_MSR_READ 0x3cc
1425+#define VGA_MSR_MEM_EN (1<<1)
1426+#define VGA_MSR_CGA_MODE (1<<0)
1427+
1428+#define VGA_SR_INDEX 0x3c4
1429+#define VGA_SR_DATA 0x3c5
1430+
1431+#define VGA_AR_INDEX 0x3c0
1432+#define VGA_AR_VID_EN (1<<5)
1433+#define VGA_AR_DATA_WRITE 0x3c0
1434+#define VGA_AR_DATA_READ 0x3c1
1435+
1436+#define VGA_GR_INDEX 0x3ce
1437+#define VGA_GR_DATA 0x3cf
1438+/* GR05 */
1439+#define VGA_GR_MEM_READ_MODE_SHIFT 3
1440+#define VGA_GR_MEM_READ_MODE_PLANE 1
1441+/* GR06 */
1442+#define VGA_GR_MEM_MODE_MASK 0xc
1443+#define VGA_GR_MEM_MODE_SHIFT 2
1444+#define VGA_GR_MEM_A0000_AFFFF 0
1445+#define VGA_GR_MEM_A0000_BFFFF 1
1446+#define VGA_GR_MEM_B0000_B7FFF 2
1447+#define VGA_GR_MEM_B0000_BFFFF 3
1448+
1449+#define VGA_DACMASK 0x3c6
1450+#define VGA_DACRX 0x3c7
1451+#define VGA_DACWX 0x3c8
1452+#define VGA_DACDATA 0x3c9
1453+
1454+#define VGA_CR_INDEX_MDA 0x3b4
1455+#define VGA_CR_DATA_MDA 0x3b5
1456+#define VGA_CR_INDEX_CGA 0x3d4
1457+#define VGA_CR_DATA_CGA 0x3d5
1458+
1459+/*
1460+ * Memory interface instructions used by the kernel
1461+ */
1462+#define MI_INSTR(opcode, flags) (((opcode) << 23) | (flags))
1463+
1464+#define MI_NOOP MI_INSTR(0, 0)
1465+#define MI_USER_INTERRUPT MI_INSTR(0x02, 0)
1466+#define MI_WAIT_FOR_EVENT MI_INSTR(0x03, 0)
1467+#define MI_WAIT_FOR_PLANE_B_FLIP (1<<6)
1468+#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2)
1469+#define MI_WAIT_FOR_PLANE_A_SCANLINES (1<<1)
1470+#define MI_FLUSH MI_INSTR(0x04, 0)
1471+#define MI_READ_FLUSH (1 << 0)
1472+#define MI_EXE_FLUSH (1 << 1)
1473+#define MI_NO_WRITE_FLUSH (1 << 2)
1474+#define MI_SCENE_COUNT (1 << 3) /* just increment scene count */
1475+#define MI_END_SCENE (1 << 4) /* flush binner and incr scene count */
1476+#define MI_BATCH_BUFFER_END MI_INSTR(0x0a, 0)
1477+#define MI_REPORT_HEAD MI_INSTR(0x07, 0)
1478+#define MI_LOAD_SCAN_LINES_INCL MI_INSTR(0x12, 0)
1479+#define MI_STORE_DWORD_IMM MI_INSTR(0x20, 1)
1480+#define MI_MEM_VIRTUAL (1 << 22) /* 965+ only */
1481+#define MI_STORE_DWORD_INDEX MI_INSTR(0x21, 1)
1482+#define MI_STORE_DWORD_INDEX_SHIFT 2
1483+#define MI_LOAD_REGISTER_IMM MI_INSTR(0x22, 1)
1484+#define MI_BATCH_BUFFER MI_INSTR(0x30, 1)
1485+#define MI_BATCH_NON_SECURE (1)
1486+#define MI_BATCH_NON_SECURE_I965 (1<<8)
1487+#define MI_BATCH_BUFFER_START MI_INSTR(0x31, 0)
1488+
1489+/*
1490+ * 3D instructions used by the kernel
1491+ */
1492+#define GFX_INSTR(opcode, flags) ((0x3 << 29) | ((opcode) << 24) | (flags))
1493+
1494+#define GFX_OP_RASTER_RULES ((0x3<<29)|(0x7<<24))
1495+#define GFX_OP_SCISSOR ((0x3<<29)|(0x1c<<24)|(0x10<<19))
1496+#define SC_UPDATE_SCISSOR (0x1<<1)
1497+#define SC_ENABLE_MASK (0x1<<0)
1498+#define SC_ENABLE (0x1<<0)
1499+#define GFX_OP_LOAD_INDIRECT ((0x3<<29)|(0x1d<<24)|(0x7<<16))
1500+#define GFX_OP_SCISSOR_INFO ((0x3<<29)|(0x1d<<24)|(0x81<<16)|(0x1))
1501+#define SCI_YMIN_MASK (0xffff<<16)
1502+#define SCI_XMIN_MASK (0xffff<<0)
1503+#define SCI_YMAX_MASK (0xffff<<16)
1504+#define SCI_XMAX_MASK (0xffff<<0)
1505+#define GFX_OP_SCISSOR_ENABLE ((0x3<<29)|(0x1c<<24)|(0x10<<19))
1506+#define GFX_OP_SCISSOR_RECT ((0x3<<29)|(0x1d<<24)|(0x81<<16)|1)
1507+#define GFX_OP_COLOR_FACTOR ((0x3<<29)|(0x1d<<24)|(0x1<<16)|0x0)
1508+#define GFX_OP_STIPPLE ((0x3<<29)|(0x1d<<24)|(0x83<<16))
1509+#define GFX_OP_MAP_INFO ((0x3<<29)|(0x1d<<24)|0x4)
1510+#define GFX_OP_DESTBUFFER_VARS ((0x3<<29)|(0x1d<<24)|(0x85<<16)|0x0)
1511+#define GFX_OP_DESTBUFFER_INFO ((0x3<<29)|(0x1d<<24)|(0x8e<<16)|1)
1512+#define GFX_OP_DRAWRECT_INFO ((0x3<<29)|(0x1d<<24)|(0x80<<16)|(0x3))
1513+#define GFX_OP_DRAWRECT_INFO_I965 ((0x7900<<16)|0x2)
1514+#define SRC_COPY_BLT_CMD ((2<<29)|(0x43<<22)|4)
1515+#define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6)
1516+#define XY_MONO_SRC_COPY_IMM_BLT ((2<<29)|(0x71<<22)|5)
1517+#define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21)
1518+#define XY_SRC_COPY_BLT_WRITE_RGB (1<<20)
1519+#define BLT_DEPTH_8 (0<<24)
1520+#define BLT_DEPTH_16_565 (1<<24)
1521+#define BLT_DEPTH_16_1555 (2<<24)
1522+#define BLT_DEPTH_32 (3<<24)
1523+#define BLT_ROP_GXCOPY (0xcc<<16)
1524+#define XY_SRC_COPY_BLT_SRC_TILED (1<<15) /* 965+ only */
1525+#define XY_SRC_COPY_BLT_DST_TILED (1<<11) /* 965+ only */
1526+#define CMD_OP_DISPLAYBUFFER_INFO ((0x0<<29)|(0x14<<23)|2)
1527+#define ASYNC_FLIP (1<<22)
1528+#define DISPLAY_PLANE_A (0<<20)
1529+#define DISPLAY_PLANE_B (1<<20)
1530+
1531+/*
1532+ * Instruction and interrupt control regs
1533+ */
1534+
1535+#define PRB0_TAIL 0x02030
1536+#define PRB0_HEAD 0x02034
1537+#define PRB0_START 0x02038
1538+#define PRB0_CTL 0x0203c
1539+#define TAIL_ADDR 0x001FFFF8
1540+#define HEAD_WRAP_COUNT 0xFFE00000
1541+#define HEAD_WRAP_ONE 0x00200000
1542+#define HEAD_ADDR 0x001FFFFC
1543+#define RING_NR_PAGES 0x001FF000
1544+#define RING_REPORT_MASK 0x00000006
1545+#define RING_REPORT_64K 0x00000002
1546+#define RING_REPORT_128K 0x00000004
1547+#define RING_NO_REPORT 0x00000000
1548+#define RING_VALID_MASK 0x00000001
1549+#define RING_VALID 0x00000001
1550+#define RING_INVALID 0x00000000
1551+#define PRB1_TAIL 0x02040 /* 915+ only */
1552+#define PRB1_HEAD 0x02044 /* 915+ only */
1553+#define PRB1_START 0x02048 /* 915+ only */
1554+#define PRB1_CTL 0x0204c /* 915+ only */
1555+#define ACTHD_I965 0x02074
1556+#define HWS_PGA 0x02080
1557+#define HWS_ADDRESS_MASK 0xfffff000
1558+#define HWS_START_ADDRESS_SHIFT 4
1559+#define IPEIR 0x02088
1560+#define NOPID 0x02094
1561+#define HWSTAM 0x02098
1562+#define SCPD0 0x0209c /* 915+ only */
1563+#define IER 0x020a0
1564+#define IIR 0x020a4
1565+#define IMR 0x020a8
1566+#define ISR 0x020ac
1567+#define I915_PIPE_CONTROL_NOTIFY_INTERRUPT (1<<18)
1568+#define I915_DISPLAY_PORT_INTERRUPT (1<<17)
1569+#define I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT (1<<15)
1570+#define I915_GMCH_THERMAL_SENSOR_EVENT_INTERRUPT (1<<14)
1571+#define I915_HWB_OOM_INTERRUPT (1<<13)
1572+#define I915_SYNC_STATUS_INTERRUPT (1<<12)
1573+#define I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT (1<<11)
1574+#define I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT (1<<10)
1575+#define I915_OVERLAY_PLANE_FLIP_PENDING_INTERRUPT (1<<9)
1576+#define I915_DISPLAY_PLANE_C_FLIP_PENDING_INTERRUPT (1<<8)
1577+#define I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT (1<<7)
1578+#define I915_DISPLAY_PIPE_A_EVENT_INTERRUPT (1<<6)
1579+#define I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT (1<<5)
1580+#define I915_DISPLAY_PIPE_B_EVENT_INTERRUPT (1<<4)
1581+#define I915_DEBUG_INTERRUPT (1<<2)
1582+#define I915_USER_INTERRUPT (1<<1)
1583+#define I915_ASLE_INTERRUPT (1<<0)
1584+#define EIR 0x020b0
1585+#define EMR 0x020b4
1586+#define ESR 0x020b8
1587+#define INSTPM 0x020c0
1588+#define ACTHD 0x020c8
1589+#define FW_BLC 0x020d8
1590+#define FW_BLC_SELF 0x020e0 /* 915+ only */
1591+#define MI_ARB_STATE 0x020e4 /* 915+ only */
1592+#define CACHE_MODE_0 0x02120 /* 915+ only */
1593+#define CM0_MASK_SHIFT 16
1594+#define CM0_IZ_OPT_DISABLE (1<<6)
1595+#define CM0_ZR_OPT_DISABLE (1<<5)
1596+#define CM0_DEPTH_EVICT_DISABLE (1<<4)
1597+#define CM0_COLOR_EVICT_DISABLE (1<<3)
1598+#define CM0_DEPTH_WRITE_DISABLE (1<<1)
1599+#define CM0_RC_OP_FLUSH_DISABLE (1<<0)
1600+#define GFX_FLSH_CNTL 0x02170 /* 915+ only */
1601+
1602+/*
1603+ * Framebuffer compression (915+ only)
1604+ */
1605+
1606+#define FBC_CFB_BASE 0x03200 /* 4k page aligned */
1607+#define FBC_LL_BASE 0x03204 /* 4k page aligned */
1608+#define FBC_CONTROL 0x03208
1609+#define FBC_CTL_EN (1<<31)
1610+#define FBC_CTL_PERIODIC (1<<30)
1611+#define FBC_CTL_INTERVAL_SHIFT (16)
1612+#define FBC_CTL_UNCOMPRESSIBLE (1<<14)
1613+#define FBC_CTL_STRIDE_SHIFT (5)
1614+#define FBC_CTL_FENCENO (1<<0)
1615+#define FBC_COMMAND 0x0320c
1616+#define FBC_CMD_COMPRESS (1<<0)
1617+#define FBC_STATUS 0x03210
1618+#define FBC_STAT_COMPRESSING (1<<31)
1619+#define FBC_STAT_COMPRESSED (1<<30)
1620+#define FBC_STAT_MODIFIED (1<<29)
1621+#define FBC_STAT_CURRENT_LINE (1<<0)
1622+#define FBC_CONTROL2 0x03214
1623+#define FBC_CTL_FENCE_DBL (0<<4)
1624+#define FBC_CTL_IDLE_IMM (0<<2)
1625+#define FBC_CTL_IDLE_FULL (1<<2)
1626+#define FBC_CTL_IDLE_LINE (2<<2)
1627+#define FBC_CTL_IDLE_DEBUG (3<<2)
1628+#define FBC_CTL_CPU_FENCE (1<<1)
1629+#define FBC_CTL_PLANEA (0<<0)
1630+#define FBC_CTL_PLANEB (1<<0)
1631+#define FBC_FENCE_OFF 0x0321b
1632+
1633+#define FBC_LL_SIZE (1536)
1634+
1635+/*
1636+ * GPIO regs
1637+ */
1638+#define GPIOA 0x5010
1639+#define GPIOB 0x5014
1640+#define GPIOC 0x5018
1641+#define GPIOD 0x501c
1642+#define GPIOE 0x5020
1643+#define GPIOF 0x5024
1644+#define GPIOG 0x5028
1645+#define GPIOH 0x502c
1646+# define GPIO_CLOCK_DIR_MASK (1 << 0)
1647+# define GPIO_CLOCK_DIR_IN (0 << 1)
1648+# define GPIO_CLOCK_DIR_OUT (1 << 1)
1649+# define GPIO_CLOCK_VAL_MASK (1 << 2)
1650+# define GPIO_CLOCK_VAL_OUT (1 << 3)
1651+# define GPIO_CLOCK_VAL_IN (1 << 4)
1652+# define GPIO_CLOCK_PULLUP_DISABLE (1 << 5)
1653+# define GPIO_DATA_DIR_MASK (1 << 8)
1654+# define GPIO_DATA_DIR_IN (0 << 9)
1655+# define GPIO_DATA_DIR_OUT (1 << 9)
1656+# define GPIO_DATA_VAL_MASK (1 << 10)
1657+# define GPIO_DATA_VAL_OUT (1 << 11)
1658+# define GPIO_DATA_VAL_IN (1 << 12)
1659+# define GPIO_DATA_PULLUP_DISABLE (1 << 13)
1660+
1661+/*
1662+ * Clock control & power management
1663+ */
1664+
1665+#define VGA0 0x6000
1666+#define VGA1 0x6004
1667+#define VGA_PD 0x6010
1668+#define VGA0_PD_P2_DIV_4 (1 << 7)
1669+#define VGA0_PD_P1_DIV_2 (1 << 5)
1670+#define VGA0_PD_P1_SHIFT 0
1671+#define VGA0_PD_P1_MASK (0x1f << 0)
1672+#define VGA1_PD_P2_DIV_4 (1 << 15)
1673+#define VGA1_PD_P1_DIV_2 (1 << 13)
1674+#define VGA1_PD_P1_SHIFT 8
1675+#define VGA1_PD_P1_MASK (0x1f << 8)
1676+#define DPLL_A 0x06014
1677+#define DPLL_B 0x06018
1678+#define DPLL_VCO_ENABLE (1 << 31)
1679+#define DPLL_DVO_HIGH_SPEED (1 << 30)
1680+#define DPLL_SYNCLOCK_ENABLE (1 << 29)
1681+#define DPLL_VGA_MODE_DIS (1 << 28)
1682+#define DPLLB_MODE_DAC_SERIAL (1 << 26) /* i915 */
1683+#define DPLLB_MODE_LVDS (2 << 26) /* i915 */
1684+#define DPLL_MODE_MASK (3 << 26)
1685+#define DPLL_DAC_SERIAL_P2_CLOCK_DIV_10 (0 << 24) /* i915 */
1686+#define DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 (1 << 24) /* i915 */
1687+#define DPLLB_LVDS_P2_CLOCK_DIV_14 (0 << 24) /* i915 */
1688+#define DPLLB_LVDS_P2_CLOCK_DIV_7 (1 << 24) /* i915 */
1689+#define DPLL_P2_CLOCK_DIV_MASK 0x03000000 /* i915 */
1690+#define DPLL_FPA01_P1_POST_DIV_MASK 0x00ff0000 /* i915 */
1691+
1692+#define I915_FIFO_UNDERRUN_STATUS (1UL<<31)
1693+#define I915_CRC_ERROR_ENABLE (1UL<<29)
1694+#define I915_CRC_DONE_ENABLE (1UL<<28)
1695+#define I915_GMBUS_EVENT_ENABLE (1UL<<27)
1696+#define I915_VSYNC_INTERRUPT_ENABLE (1UL<<25)
1697+#define I915_DISPLAY_LINE_COMPARE_ENABLE (1UL<<24)
1698+#define I915_DPST_EVENT_ENABLE (1UL<<23)
1699+#define I915_LEGACY_BLC_EVENT_ENABLE (1UL<<22)
1700+#define I915_ODD_FIELD_INTERRUPT_ENABLE (1UL<<21)
1701+#define I915_EVEN_FIELD_INTERRUPT_ENABLE (1UL<<20)
1702+#define I915_START_VBLANK_INTERRUPT_ENABLE (1UL<<18) /* 965 or later */
1703+#define I915_VBLANK_INTERRUPT_ENABLE (1UL<<17)
1704+#define I915_OVERLAY_UPDATED_ENABLE (1UL<<16)
1705+#define I915_CRC_ERROR_INTERRUPT_STATUS (1UL<<13)
1706+#define I915_CRC_DONE_INTERRUPT_STATUS (1UL<<12)
1707+#define I915_GMBUS_INTERRUPT_STATUS (1UL<<11)
1708+#define I915_VSYNC_INTERRUPT_STATUS (1UL<<9)
1709+#define I915_DISPLAY_LINE_COMPARE_STATUS (1UL<<8)
1710+#define I915_DPST_EVENT_STATUS (1UL<<7)
1711+#define I915_LEGACY_BLC_EVENT_STATUS (1UL<<6)
1712+#define I915_ODD_FIELD_INTERRUPT_STATUS (1UL<<5)
1713+#define I915_EVEN_FIELD_INTERRUPT_STATUS (1UL<<4)
1714+#define I915_START_VBLANK_INTERRUPT_STATUS (1UL<<2) /* 965 or later */
1715+#define I915_VBLANK_INTERRUPT_STATUS (1UL<<1)
1716+#define I915_OVERLAY_UPDATED_STATUS (1UL<<0)
1717+
1718+#define SRX_INDEX 0x3c4
1719+#define SRX_DATA 0x3c5
1720+#define SR01 1
1721+#define SR01_SCREEN_OFF (1<<5)
1722+
1723+#define PPCR 0x61204
1724+#define PPCR_ON (1<<0)
1725+
1726+#define DVOB 0x61140
1727+#define DVOB_ON (1<<31)
1728+#define DVOC 0x61160
1729+#define DVOC_ON (1<<31)
1730+#define LVDS 0x61180
1731+#define LVDS_ON (1<<31)
1732+
1733+#define ADPA 0x61100
1734+#define ADPA_DPMS_MASK (~(3<<10))
1735+#define ADPA_DPMS_ON (0<<10)
1736+#define ADPA_DPMS_SUSPEND (1<<10)
1737+#define ADPA_DPMS_STANDBY (2<<10)
1738+#define ADPA_DPMS_OFF (3<<10)
1739+
1740+#define RING_TAIL 0x00
1741+#define TAIL_ADDR 0x001FFFF8
1742+#define RING_HEAD 0x04
1743+#define HEAD_WRAP_COUNT 0xFFE00000
1744+#define HEAD_WRAP_ONE 0x00200000
1745+#define HEAD_ADDR 0x001FFFFC
1746+#define RING_START 0x08
1747+#define START_ADDR 0xFFFFF000
1748+#define RING_LEN 0x0C
1749+#define RING_NR_PAGES 0x001FF000
1750+#define RING_REPORT_MASK 0x00000006
1751+#define RING_REPORT_64K 0x00000002
1752+#define RING_REPORT_128K 0x00000004
1753+#define RING_NO_REPORT 0x00000000
1754+#define RING_VALID_MASK 0x00000001
1755+#define RING_VALID 0x00000001
1756+#define RING_INVALID 0x00000000
1757+
1758+/* Scratch pad debug 0 reg:
1759+ */
1760+#define DPLL_FPA01_P1_POST_DIV_MASK_I830 0x001f0000
1761+/*
1762+ * The i830 generation, in LVDS mode, defines P1 as the bit number set within
1763+ * this field (only one bit may be set).
1764+ */
1765+#define DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS 0x003f0000
1766+#define DPLL_FPA01_P1_POST_DIV_SHIFT 16
1767+/* i830, required in DVO non-gang */
1768+#define PLL_P2_DIVIDE_BY_4 (1 << 23)
1769+#define PLL_P1_DIVIDE_BY_TWO (1 << 21) /* i830 */
1770+#define PLL_REF_INPUT_DREFCLK (0 << 13)
1771+#define PLL_REF_INPUT_TVCLKINA (1 << 13) /* i830 */
1772+#define PLL_REF_INPUT_TVCLKINBC (2 << 13) /* SDVO TVCLKIN */
1773+#define PLLB_REF_INPUT_SPREADSPECTRUMIN (3 << 13)
1774+#define PLL_REF_INPUT_MASK (3 << 13)
1775+#define PLL_LOAD_PULSE_PHASE_SHIFT 9
1776+/*
1777+ * Parallel to Serial Load Pulse phase selection.
1778+ * Selects the phase for the 10X DPLL clock for the PCIe
1779+ * digital display port. The range is 4 to 13; 10 or more
1780+ * is just a flip delay. The default is 6
1781+ */
1782+#define PLL_LOAD_PULSE_PHASE_MASK (0xf << PLL_LOAD_PULSE_PHASE_SHIFT)
1783+#define DISPLAY_RATE_SELECT_FPA1 (1 << 8)
1784+/*
1785+ * SDVO multiplier for 945G/GM. Not used on 965.
1786+ */
1787+#define SDVO_MULTIPLIER_MASK 0x000000ff
1788+#define SDVO_MULTIPLIER_SHIFT_HIRES 4
1789+#define SDVO_MULTIPLIER_SHIFT_VGA 0
1790+#define DPLL_A_MD 0x0601c /* 965+ only */
1791+/*
1792+ * UDI pixel divider, controlling how many pixels are stuffed into a packet.
1793+ *
1794+ * Value is pixels minus 1. Must be set to 1 pixel for SDVO.
1795+ */
1796+#define DPLL_MD_UDI_DIVIDER_MASK 0x3f000000
1797+#define DPLL_MD_UDI_DIVIDER_SHIFT 24
1798+/* UDI pixel divider for VGA, same as DPLL_MD_UDI_DIVIDER_MASK. */
1799+#define DPLL_MD_VGA_UDI_DIVIDER_MASK 0x003f0000
1800+#define DPLL_MD_VGA_UDI_DIVIDER_SHIFT 16
1801+/*
1802+ * SDVO/UDI pixel multiplier.
1803+ *
1804+ * SDVO requires that the bus clock rate be between 1 and 2 Ghz, and the bus
1805+ * clock rate is 10 times the DPLL clock. At low resolution/refresh rate
1806+ * modes, the bus rate would be below the limits, so SDVO allows for stuffing
1807+ * dummy bytes in the datastream at an increased clock rate, with both sides of
1808+ * the link knowing how many bytes are fill.
1809+ *
1810+ * So, for a mode with a dotclock of 65Mhz, we would want to double the clock
1811+ * rate to 130Mhz to get a bus rate of 1.30Ghz. The DPLL clock rate would be
1812+ * set to 130Mhz, and the SDVO multiplier set to 2x in this register and
1813+ * through an SDVO command.
1814+ *
1815+ * This register field has values of multiplication factor minus 1, with
1816+ * a maximum multiplier of 5 for SDVO.
1817+ */
1818+#define DPLL_MD_UDI_MULTIPLIER_MASK 0x00003f00
1819+#define DPLL_MD_UDI_MULTIPLIER_SHIFT 8
1820+/*
1821+ * SDVO/UDI pixel multiplier for VGA, same as DPLL_MD_UDI_MULTIPLIER_MASK.
1822+ * This best be set to the default value (3) or the CRT won't work. No,
1823+ * I don't entirely understand what this does...
1824+ */
1825+#define DPLL_MD_VGA_UDI_MULTIPLIER_MASK 0x0000003f
1826+#define DPLL_MD_VGA_UDI_MULTIPLIER_SHIFT 0
1827+#define DPLL_B_MD 0x06020 /* 965+ only */
1828+#define FPA0 0x06040
1829+#define FPA1 0x06044
1830+#define FPB0 0x06048
1831+#define FPB1 0x0604c
1832+#define FP_N_DIV_MASK 0x003f0000
1833+#define FP_N_DIV_SHIFT 16
1834+#define FP_M1_DIV_MASK 0x00003f00
1835+#define FP_M1_DIV_SHIFT 8
1836+#define FP_M2_DIV_MASK 0x0000003f
1837+#define FP_M2_DIV_SHIFT 0
1838+#define DPLL_TEST 0x606c
1839+#define DPLLB_TEST_SDVO_DIV_1 (0 << 22)
1840+#define DPLLB_TEST_SDVO_DIV_2 (1 << 22)
1841+#define DPLLB_TEST_SDVO_DIV_4 (2 << 22)
1842+#define DPLLB_TEST_SDVO_DIV_MASK (3 << 22)
1843+#define DPLLB_TEST_N_BYPASS (1 << 19)
1844+#define DPLLB_TEST_M_BYPASS (1 << 18)
1845+#define DPLLB_INPUT_BUFFER_ENABLE (1 << 16)
1846+#define DPLLA_TEST_N_BYPASS (1 << 3)
1847+#define DPLLA_TEST_M_BYPASS (1 << 2)
1848+#define DPLLA_INPUT_BUFFER_ENABLE (1 << 0)
1849+#define D_STATE 0x6104
1850+#define CG_2D_DIS 0x6200
1851+#define CG_3D_DIS 0x6204
1852+
1853+/*
1854+ * Palette regs
1855+ */
1856+
1857+#define PALETTE_A 0x0a000
1858+#define PALETTE_B 0x0a800
1859+
1860+/*
1861+ * Overlay regs
1862+ */
1863+
1864+#define OVADD 0x30000
1865+#define DOVSTA 0x30008
1866+#define OC_BUF (0x3<<20)
1867+#define OGAMC5 0x30010
1868+#define OGAMC4 0x30014
1869+#define OGAMC3 0x30018
1870+#define OGAMC2 0x3001c
1871+#define OGAMC1 0x30020
1872+#define OGAMC0 0x30024
1873+
1874+/*
1875+ * Display engine regs
1876+ */
1877+
1878+/* Pipe A timing regs */
1879+#define HTOTAL_A 0x60000
1880+#define HBLANK_A 0x60004
1881+#define HSYNC_A 0x60008
1882+#define VTOTAL_A 0x6000c
1883+#define VBLANK_A 0x60010
1884+#define VSYNC_A 0x60014
1885+#define PIPEASRC 0x6001c
1886+#define BCLRPAT_A 0x60020
1887+
1888+/* Pipe B timing regs */
1889+#define HTOTAL_B 0x61000
1890+#define HBLANK_B 0x61004
1891+#define HSYNC_B 0x61008
1892+#define VTOTAL_B 0x6100c
1893+#define VBLANK_B 0x61010
1894+#define VSYNC_B 0x61014
1895+#define PIPEBSRC 0x6101c
1896+#define BCLRPAT_B 0x61020
1897+
1898+/* VGA port control */
1899+#define ADPA 0x61100
1900+#define ADPA_DAC_ENABLE (1<<31)
1901+#define ADPA_DAC_DISABLE 0
1902+#define ADPA_PIPE_SELECT_MASK (1<<30)
1903+#define ADPA_PIPE_A_SELECT 0
1904+#define ADPA_PIPE_B_SELECT (1<<30)
1905+#define ADPA_USE_VGA_HVPOLARITY (1<<15)
1906+#define ADPA_SETS_HVPOLARITY 0
1907+#define ADPA_VSYNC_CNTL_DISABLE (1<<11)
1908+#define ADPA_VSYNC_CNTL_ENABLE 0
1909+#define ADPA_HSYNC_CNTL_DISABLE (1<<10)
1910+#define ADPA_HSYNC_CNTL_ENABLE 0
1911+#define ADPA_VSYNC_ACTIVE_HIGH (1<<4)
1912+#define ADPA_VSYNC_ACTIVE_LOW 0
1913+#define ADPA_HSYNC_ACTIVE_HIGH (1<<3)
1914+#define ADPA_HSYNC_ACTIVE_LOW 0
1915+#define ADPA_DPMS_MASK (~(3<<10))
1916+#define ADPA_DPMS_ON (0<<10)
1917+#define ADPA_DPMS_SUSPEND (1<<10)
1918+#define ADPA_DPMS_STANDBY (2<<10)
1919+#define ADPA_DPMS_OFF (3<<10)
1920+
1921+/* Hotplug control (945+ only) */
1922+#define PORT_HOTPLUG_EN 0x61110
1923+#define SDVOB_HOTPLUG_INT_EN (1 << 26)
1924+#define SDVOC_HOTPLUG_INT_EN (1 << 25)
1925+#define TV_HOTPLUG_INT_EN (1 << 18)
1926+#define CRT_HOTPLUG_INT_EN (1 << 9)
1927+#define CRT_HOTPLUG_FORCE_DETECT (1 << 3)
1928+
1929+#define PORT_HOTPLUG_STAT 0x61114
1930+#define CRT_HOTPLUG_INT_STATUS (1 << 11)
1931+#define TV_HOTPLUG_INT_STATUS (1 << 10)
1932+#define CRT_HOTPLUG_MONITOR_MASK (3 << 8)
1933+#define CRT_HOTPLUG_MONITOR_COLOR (3 << 8)
1934+#define CRT_HOTPLUG_MONITOR_MONO (2 << 8)
1935+#define CRT_HOTPLUG_MONITOR_NONE (0 << 8)
1936+#define SDVOC_HOTPLUG_INT_STATUS (1 << 7)
1937+#define SDVOB_HOTPLUG_INT_STATUS (1 << 6)
1938+
1939+/* SDVO port control */
1940+#define SDVOB 0x61140
1941+#define SDVOC 0x61160
1942+#define SDVO_ENABLE (1 << 31)
1943+#define SDVO_PIPE_B_SELECT (1 << 30)
1944+#define SDVO_STALL_SELECT (1 << 29)
1945+#define SDVO_INTERRUPT_ENABLE (1 << 26)
1946+/**
1947+ * 915G/GM SDVO pixel multiplier.
1948+ *
1949+ * Programmed value is multiplier - 1, up to 5x.
1950+ *
1951+ * \sa DPLL_MD_UDI_MULTIPLIER_MASK
1952+ */
1953+#define SDVO_PORT_MULTIPLY_MASK (7 << 23)
1954+#define SDVO_PORT_MULTIPLY_SHIFT 23
1955+#define SDVO_PHASE_SELECT_MASK (15 << 19)
1956+#define SDVO_PHASE_SELECT_DEFAULT (6 << 19)
1957+#define SDVO_CLOCK_OUTPUT_INVERT (1 << 18)
1958+#define SDVOC_GANG_MODE (1 << 16)
1959+#define SDVO_BORDER_ENABLE (1 << 7)
1960+#define SDVOB_PCIE_CONCURRENCY (1 << 3)
1961+#define SDVO_DETECTED (1 << 2)
1962+/* Bits to be preserved when writing */
1963+#define SDVOB_PRESERVE_MASK ((1 << 17) | (1 << 16) | (1 << 14) | (1 << 26))
1964+#define SDVOC_PRESERVE_MASK ((1 << 17) | (1 << 26))
1965+
1966+/* DVO port control */
1967+#define DVOA 0x61120
1968+#define DVOB 0x61140
1969+#define DVOC 0x61160
1970+#define DVO_ENABLE (1 << 31)
1971+#define DVO_PIPE_B_SELECT (1 << 30)
1972+#define DVO_PIPE_STALL_UNUSED (0 << 28)
1973+#define DVO_PIPE_STALL (1 << 28)
1974+#define DVO_PIPE_STALL_TV (2 << 28)
1975+#define DVO_PIPE_STALL_MASK (3 << 28)
1976+#define DVO_USE_VGA_SYNC (1 << 15)
1977+#define DVO_DATA_ORDER_I740 (0 << 14)
1978+#define DVO_DATA_ORDER_FP (1 << 14)
1979+#define DVO_VSYNC_DISABLE (1 << 11)
1980+#define DVO_HSYNC_DISABLE (1 << 10)
1981+#define DVO_VSYNC_TRISTATE (1 << 9)
1982+#define DVO_HSYNC_TRISTATE (1 << 8)
1983+#define DVO_BORDER_ENABLE (1 << 7)
1984+#define DVO_DATA_ORDER_GBRG (1 << 6)
1985+#define DVO_DATA_ORDER_RGGB (0 << 6)
1986+#define DVO_DATA_ORDER_GBRG_ERRATA (0 << 6)
1987+#define DVO_DATA_ORDER_RGGB_ERRATA (1 << 6)
1988+#define DVO_VSYNC_ACTIVE_HIGH (1 << 4)
1989+#define DVO_HSYNC_ACTIVE_HIGH (1 << 3)
1990+#define DVO_BLANK_ACTIVE_HIGH (1 << 2)
1991+#define DVO_OUTPUT_CSTATE_PIXELS (1 << 1) /* SDG only */
1992+#define DVO_OUTPUT_SOURCE_SIZE_PIXELS (1 << 0) /* SDG only */
1993+#define DVO_PRESERVE_MASK (0x7<<24)
1994+#define DVOA_SRCDIM 0x61124
1995+#define DVOB_SRCDIM 0x61144
1996+#define DVOC_SRCDIM 0x61164
1997+#define DVO_SRCDIM_HORIZONTAL_SHIFT 12
1998+#define DVO_SRCDIM_VERTICAL_SHIFT 0
1999+
2000+/* LVDS port control */
2001+#define LVDS 0x61180
2002+/*
2003+ * Enables the LVDS port. This bit must be set before DPLLs are enabled, as
2004+ * the DPLL semantics change when the LVDS is assigned to that pipe.
2005+ */
2006+#define LVDS_PORT_EN (1 << 31)
2007+/* Selects pipe B for LVDS data. Must be set on pre-965. */
2008+#define LVDS_PIPEB_SELECT (1 << 30)
2009+/*
2010+ * Enables the A0-A2 data pairs and CLKA, containing 18 bits of color data per
2011+ * pixel.
2012+ */
2013+#define LVDS_A0A2_CLKA_POWER_MASK (3 << 8)
2014+#define LVDS_A0A2_CLKA_POWER_DOWN (0 << 8)
2015+#define LVDS_A0A2_CLKA_POWER_UP (3 << 8)
2016+/*
2017+ * Controls the A3 data pair, which contains the additional LSBs for 24 bit
2018+ * mode. Only enabled if LVDS_A0A2_CLKA_POWER_UP also indicates it should be
2019+ * on.
2020+ */
2021+#define LVDS_A3_POWER_MASK (3 << 6)
2022+#define LVDS_A3_POWER_DOWN (0 << 6)
2023+#define LVDS_A3_POWER_UP (3 << 6)
2024+/*
2025+ * Controls the CLKB pair. This should only be set when LVDS_B0B3_POWER_UP
2026+ * is set.
2027+ */
2028+#define LVDS_CLKB_POWER_MASK (3 << 4)
2029+#define LVDS_CLKB_POWER_DOWN (0 << 4)
2030+#define LVDS_CLKB_POWER_UP (3 << 4)
2031+/*
2032+ * Controls the B0-B3 data pairs. This must be set to match the DPLL p2
2033+ * setting for whether we are in dual-channel mode. The B3 pair will
2034+ * additionally only be powered up when LVDS_A3_POWER_UP is set.
2035+ */
2036+#define LVDS_B0B3_POWER_MASK (3 << 2)
2037+#define LVDS_B0B3_POWER_DOWN (0 << 2)
2038+#define LVDS_B0B3_POWER_UP (3 << 2)
2039+
2040+/* Panel power sequencing */
2041+#define PP_STATUS 0x61200
2042+#define PP_ON (1 << 31)
2043+/*
2044+ * Indicates that all dependencies of the panel are on:
2045+ *
2046+ * - PLL enabled
2047+ * - pipe enabled
2048+ * - LVDS/DVOB/DVOC on
2049+ */
2050+#define PP_READY (1 << 30)
2051+#define PP_SEQUENCE_NONE (0 << 28)
2052+#define PP_SEQUENCE_ON (1 << 28)
2053+#define PP_SEQUENCE_OFF (2 << 28)
2054+#define PP_SEQUENCE_MASK 0x30000000
2055+#define PP_CONTROL 0x61204
2056+#define POWER_TARGET_ON (1 << 0)
2057+#define PP_ON_DELAYS 0x61208
2058+#define PP_OFF_DELAYS 0x6120c
2059+#define PP_DIVISOR 0x61210
2060+
2061+/* Panel fitting */
2062+#define PFIT_CONTROL 0x61230
2063+#define PFIT_ENABLE (1 << 31)
2064+#define PFIT_PIPE_MASK (3 << 29)
2065+#define PFIT_PIPE_SHIFT 29
2066+#define VERT_INTERP_DISABLE (0 << 10)
2067+#define VERT_INTERP_BILINEAR (1 << 10)
2068+#define VERT_INTERP_MASK (3 << 10)
2069+#define VERT_AUTO_SCALE (1 << 9)
2070+#define HORIZ_INTERP_DISABLE (0 << 6)
2071+#define HORIZ_INTERP_BILINEAR (1 << 6)
2072+#define HORIZ_INTERP_MASK (3 << 6)
2073+#define HORIZ_AUTO_SCALE (1 << 5)
2074+#define PANEL_8TO6_DITHER_ENABLE (1 << 3)
2075+#define PFIT_PGM_RATIOS 0x61234
2076+#define PFIT_VERT_SCALE_MASK 0xfff00000
2077+#define PFIT_HORIZ_SCALE_MASK 0x0000fff0
2078+#define PFIT_AUTO_RATIOS 0x61238
2079+
2080+/* Backlight control */
2081+#define BLC_PWM_CTL 0x61254
2082+#define BACKLIGHT_MODULATION_FREQ_SHIFT (17)
2083+#define BLC_PWM_CTL2 0x61250 /* 965+ only */
2084+/*
2085+ * This is the most significant 15 bits of the number of backlight cycles in a
2086+ * complete cycle of the modulated backlight control.
2087+ *
2088+ * The actual value is this field multiplied by two.
2089+ */
2090+#define BACKLIGHT_MODULATION_FREQ_MASK (0x7fff << 17)
2091+#define BLM_LEGACY_MODE (1 << 16)
2092+/*
2093+ * This is the number of cycles out of the backlight modulation cycle for which
2094+ * the backlight is on.
2095+ *
2096+ * This field must be no greater than the number of cycles in the complete
2097+ * backlight modulation cycle.
2098+ */
2099+#define BACKLIGHT_DUTY_CYCLE_SHIFT (0)
2100+#define BACKLIGHT_DUTY_CYCLE_MASK (0xffff)
2101+
2102+/* TV port control */
2103+#define TV_CTL 0x68000
2104+/** Enables the TV encoder */
2105+# define TV_ENC_ENABLE (1 << 31)
2106+/** Sources the TV encoder input from pipe B instead of A. */
2107+# define TV_ENC_PIPEB_SELECT (1 << 30)
2108+/** Outputs composite video (DAC A only) */
2109+# define TV_ENC_OUTPUT_COMPOSITE (0 << 28)
2110+/** Outputs SVideo video (DAC B/C) */
2111+# define TV_ENC_OUTPUT_SVIDEO (1 << 28)
2112+/** Outputs Component video (DAC A/B/C) */
2113+# define TV_ENC_OUTPUT_COMPONENT (2 << 28)
2114+/** Outputs Composite and SVideo (DAC A/B/C) */
2115+# define TV_ENC_OUTPUT_SVIDEO_COMPOSITE (3 << 28)
2116+# define TV_TRILEVEL_SYNC (1 << 21)
2117+/** Enables slow sync generation (945GM only) */
2118+# define TV_SLOW_SYNC (1 << 20)
2119+/** Selects 4x oversampling for 480i and 576p */
2120+# define TV_OVERSAMPLE_4X (0 << 18)
2121+/** Selects 2x oversampling for 720p and 1080i */
2122+# define TV_OVERSAMPLE_2X (1 << 18)
2123+/** Selects no oversampling for 1080p */
2124+# define TV_OVERSAMPLE_NONE (2 << 18)
2125+/** Selects 8x oversampling */
2126+# define TV_OVERSAMPLE_8X (3 << 18)
2127+/** Selects progressive mode rather than interlaced */
2128+# define TV_PROGRESSIVE (1 << 17)
2129+/** Sets the colorburst to PAL mode. Required for non-M PAL modes. */
2130+# define TV_PAL_BURST (1 << 16)
2131+/** Field for setting delay of Y compared to C */
2132+# define TV_YC_SKEW_MASK (7 << 12)
2133+/** Enables a fix for 480p/576p standard definition modes on the 915GM only */
2134+# define TV_ENC_SDP_FIX (1 << 11)
2135+/**
2136+ * Enables a fix for the 915GM only.
2137+ *
2138+ * Not sure what it does.
2139+ */
2140+# define TV_ENC_C0_FIX (1 << 10)
2141+/** Bits that must be preserved by software */
2142+# define TV_CTL_SAVE ((3 << 8) | (3 << 6))
2143+# define TV_FUSE_STATE_MASK (3 << 4)
2144+/** Read-only state that reports all features enabled */
2145+# define TV_FUSE_STATE_ENABLED (0 << 4)
2146+/** Read-only state that reports that Macrovision is disabled in hardware*/
2147+# define TV_FUSE_STATE_NO_MACROVISION (1 << 4)
2148+/** Read-only state that reports that TV-out is disabled in hardware. */
2149+# define TV_FUSE_STATE_DISABLED (2 << 4)
2150+/** Normal operation */
2151+# define TV_TEST_MODE_NORMAL (0 << 0)
2152+/** Encoder test pattern 1 - combo pattern */
2153+# define TV_TEST_MODE_PATTERN_1 (1 << 0)
2154+/** Encoder test pattern 2 - full screen vertical 75% color bars */
2155+# define TV_TEST_MODE_PATTERN_2 (2 << 0)
2156+/** Encoder test pattern 3 - full screen horizontal 75% color bars */
2157+# define TV_TEST_MODE_PATTERN_3 (3 << 0)
2158+/** Encoder test pattern 4 - random noise */
2159+# define TV_TEST_MODE_PATTERN_4 (4 << 0)
2160+/** Encoder test pattern 5 - linear color ramps */
2161+# define TV_TEST_MODE_PATTERN_5 (5 << 0)
2162+/**
2163+ * This test mode forces the DACs to 50% of full output.
2164+ *
2165+ * This is used for load detection in combination with TVDAC_SENSE_MASK
2166+ */
2167+# define TV_TEST_MODE_MONITOR_DETECT (7 << 0)
2168+# define TV_TEST_MODE_MASK (7 << 0)
2169+
2170+#define TV_DAC 0x68004
2171+/**
2172+ * Reports that DAC state change logic has reported change (RO).
2173+ *
2174+ * This gets cleared when TV_DAC_STATE_EN is cleared
2175+*/
2176+# define TVDAC_STATE_CHG (1 << 31)
2177+# define TVDAC_SENSE_MASK (7 << 28)
2178+/** Reports that DAC A voltage is above the detect threshold */
2179+# define TVDAC_A_SENSE (1 << 30)
2180+/** Reports that DAC B voltage is above the detect threshold */
2181+# define TVDAC_B_SENSE (1 << 29)
2182+/** Reports that DAC C voltage is above the detect threshold */
2183+# define TVDAC_C_SENSE (1 << 28)
2184+/**
2185+ * Enables DAC state detection logic, for load-based TV detection.
2186+ *
2187+ * The PLL of the chosen pipe (in TV_CTL) must be running, and the encoder set
2188+ * to off, for load detection to work.
2189+ */
2190+# define TVDAC_STATE_CHG_EN (1 << 27)
2191+/** Sets the DAC A sense value to high */
2192+# define TVDAC_A_SENSE_CTL (1 << 26)
2193+/** Sets the DAC B sense value to high */
2194+# define TVDAC_B_SENSE_CTL (1 << 25)
2195+/** Sets the DAC C sense value to high */
2196+# define TVDAC_C_SENSE_CTL (1 << 24)
2197+/** Overrides the ENC_ENABLE and DAC voltage levels */
2198+# define DAC_CTL_OVERRIDE (1 << 7)
2199+/** Sets the slew rate. Must be preserved in software */
2200+# define ENC_TVDAC_SLEW_FAST (1 << 6)
2201+# define DAC_A_1_3_V (0 << 4)
2202+# define DAC_A_1_1_V (1 << 4)
2203+# define DAC_A_0_7_V (2 << 4)
2204+# define DAC_A_OFF (3 << 4)
2205+# define DAC_B_1_3_V (0 << 2)
2206+# define DAC_B_1_1_V (1 << 2)
2207+# define DAC_B_0_7_V (2 << 2)
2208+# define DAC_B_OFF (3 << 2)
2209+# define DAC_C_1_3_V (0 << 0)
2210+# define DAC_C_1_1_V (1 << 0)
2211+# define DAC_C_0_7_V (2 << 0)
2212+# define DAC_C_OFF (3 << 0)
2213+
2214+/**
2215+ * CSC coefficients are stored in a floating point format with 9 bits of
2216+ * mantissa and 2 or 3 bits of exponent. The exponent is represented as 2**-n,
2217+ * where 2-bit exponents are unsigned n, and 3-bit exponents are signed n with
2218+ * -1 (0x3) being the only legal negative value.
2219+ */
2220+#define TV_CSC_Y 0x68010
2221+# define TV_RY_MASK 0x07ff0000
2222+# define TV_RY_SHIFT 16
2223+# define TV_GY_MASK 0x00000fff
2224+# define TV_GY_SHIFT 0
2225+
2226+#define TV_CSC_Y2 0x68014
2227+# define TV_BY_MASK 0x07ff0000
2228+# define TV_BY_SHIFT 16
2229+/**
2230+ * Y attenuation for component video.
2231+ *
2232+ * Stored in 1.9 fixed point.
2233+ */
2234+# define TV_AY_MASK 0x000003ff
2235+# define TV_AY_SHIFT 0
2236+
2237+#define TV_CSC_U 0x68018
2238+# define TV_RU_MASK 0x07ff0000
2239+# define TV_RU_SHIFT 16
2240+# define TV_GU_MASK 0x000007ff
2241+# define TV_GU_SHIFT 0
2242+
2243+#define TV_CSC_U2 0x6801c
2244+# define TV_BU_MASK 0x07ff0000
2245+# define TV_BU_SHIFT 16
2246+/**
2247+ * U attenuation for component video.
2248+ *
2249+ * Stored in 1.9 fixed point.
2250+ */
2251+# define TV_AU_MASK 0x000003ff
2252+# define TV_AU_SHIFT 0
2253+
2254+#define TV_CSC_V 0x68020
2255+# define TV_RV_MASK 0x0fff0000
2256+# define TV_RV_SHIFT 16
2257+# define TV_GV_MASK 0x000007ff
2258+# define TV_GV_SHIFT 0
2259+
2260+#define TV_CSC_V2 0x68024
2261+# define TV_BV_MASK 0x07ff0000
2262+# define TV_BV_SHIFT 16
2263+/**
2264+ * V attenuation for component video.
2265+ *
2266+ * Stored in 1.9 fixed point.
2267+ */
2268+# define TV_AV_MASK 0x000007ff
2269+# define TV_AV_SHIFT 0
2270+
2271+#define TV_CLR_KNOBS 0x68028
2272+/** 2s-complement brightness adjustment */
2273+# define TV_BRIGHTNESS_MASK 0xff000000
2274+# define TV_BRIGHTNESS_SHIFT 24
2275+/** Contrast adjustment, as a 2.6 unsigned floating point number */
2276+# define TV_CONTRAST_MASK 0x00ff0000
2277+# define TV_CONTRAST_SHIFT 16
2278+/** Saturation adjustment, as a 2.6 unsigned floating point number */
2279+# define TV_SATURATION_MASK 0x0000ff00
2280+# define TV_SATURATION_SHIFT 8
2281+/** Hue adjustment, as an integer phase angle in degrees */
2282+# define TV_HUE_MASK 0x000000ff
2283+# define TV_HUE_SHIFT 0
2284+
2285+#define TV_CLR_LEVEL 0x6802c
2286+/** Controls the DAC level for black */
2287+# define TV_BLACK_LEVEL_MASK 0x01ff0000
2288+# define TV_BLACK_LEVEL_SHIFT 16
2289+/** Controls the DAC level for blanking */
2290+# define TV_BLANK_LEVEL_MASK 0x000001ff
2291+# define TV_BLANK_LEVEL_SHIFT 0
2292+
2293+#define TV_H_CTL_1 0x68030
2294+/** Number of pixels in the hsync. */
2295+# define TV_HSYNC_END_MASK 0x1fff0000
2296+# define TV_HSYNC_END_SHIFT 16
2297+/** Total number of pixels minus one in the line (display and blanking). */
2298+# define TV_HTOTAL_MASK 0x00001fff
2299+# define TV_HTOTAL_SHIFT 0
2300+
2301+#define TV_H_CTL_2 0x68034
2302+/** Enables the colorburst (needed for non-component color) */
2303+# define TV_BURST_ENA (1 << 31)
2304+/** Offset of the colorburst from the start of hsync, in pixels minus one. */
2305+# define TV_HBURST_START_SHIFT 16
2306+# define TV_HBURST_START_MASK 0x1fff0000
2307+/** Length of the colorburst */
2308+# define TV_HBURST_LEN_SHIFT 0
2309+# define TV_HBURST_LEN_MASK 0x0001fff
2310+
2311+#define TV_H_CTL_3 0x68038
2312+/** End of hblank, measured in pixels minus one from start of hsync */
2313+# define TV_HBLANK_END_SHIFT 16
2314+# define TV_HBLANK_END_MASK 0x1fff0000
2315+/** Start of hblank, measured in pixels minus one from start of hsync */
2316+# define TV_HBLANK_START_SHIFT 0
2317+# define TV_HBLANK_START_MASK 0x0001fff
2318+
2319+#define TV_V_CTL_1 0x6803c
2320+/** XXX */
2321+# define TV_NBR_END_SHIFT 16
2322+# define TV_NBR_END_MASK 0x07ff0000
2323+/** XXX */
2324+# define TV_VI_END_F1_SHIFT 8
2325+# define TV_VI_END_F1_MASK 0x00003f00
2326+/** XXX */
2327+# define TV_VI_END_F2_SHIFT 0
2328+# define TV_VI_END_F2_MASK 0x0000003f
2329+
2330+#define TV_V_CTL_2 0x68040
2331+/** Length of vsync, in half lines */
2332+# define TV_VSYNC_LEN_MASK 0x07ff0000
2333+# define TV_VSYNC_LEN_SHIFT 16
2334+/** Offset of the start of vsync in field 1, measured in one less than the
2335+ * number of half lines.
2336+ */
2337+# define TV_VSYNC_START_F1_MASK 0x00007f00
2338+# define TV_VSYNC_START_F1_SHIFT 8
2339+/**
2340+ * Offset of the start of vsync in field 2, measured in one less than the
2341+ * number of half lines.
2342+ */
2343+# define TV_VSYNC_START_F2_MASK 0x0000007f
2344+# define TV_VSYNC_START_F2_SHIFT 0
2345+
2346+#define TV_V_CTL_3 0x68044
2347+/** Enables generation of the equalization signal */
2348+# define TV_EQUAL_ENA (1 << 31)
2349+/** Length of vsync, in half lines */
2350+# define TV_VEQ_LEN_MASK 0x007f0000
2351+# define TV_VEQ_LEN_SHIFT 16
2352+/** Offset of the start of equalization in field 1, measured in one less than
2353+ * the number of half lines.
2354+ */
2355+# define TV_VEQ_START_F1_MASK 0x0007f00
2356+# define TV_VEQ_START_F1_SHIFT 8
2357+/**
2358+ * Offset of the start of equalization in field 2, measured in one less than
2359+ * the number of half lines.
2360+ */
2361+# define TV_VEQ_START_F2_MASK 0x000007f
2362+# define TV_VEQ_START_F2_SHIFT 0
2363+
2364+#define TV_V_CTL_4 0x68048
2365+/**
2366+ * Offset to start of vertical colorburst, measured in one less than the
2367+ * number of lines from vertical start.
2368+ */
2369+# define TV_VBURST_START_F1_MASK 0x003f0000
2370+# define TV_VBURST_START_F1_SHIFT 16
2371+/**
2372+ * Offset to the end of vertical colorburst, measured in one less than the
2373+ * number of lines from the start of NBR.
2374+ */
2375+# define TV_VBURST_END_F1_MASK 0x000000ff
2376+# define TV_VBURST_END_F1_SHIFT 0
2377+
2378+#define TV_V_CTL_5 0x6804c
2379+/**
2380+ * Offset to start of vertical colorburst, measured in one less than the
2381+ * number of lines from vertical start.
2382+ */
2383+# define TV_VBURST_START_F2_MASK 0x003f0000
2384+# define TV_VBURST_START_F2_SHIFT 16
2385+/**
2386+ * Offset to the end of vertical colorburst, measured in one less than the
2387+ * number of lines from the start of NBR.
2388+ */
2389+# define TV_VBURST_END_F2_MASK 0x000000ff
2390+# define TV_VBURST_END_F2_SHIFT 0
2391+
2392+#define TV_V_CTL_6 0x68050
2393+/**
2394+ * Offset to start of vertical colorburst, measured in one less than the
2395+ * number of lines from vertical start.
2396+ */
2397+# define TV_VBURST_START_F3_MASK 0x003f0000
2398+# define TV_VBURST_START_F3_SHIFT 16
2399+/**
2400+ * Offset to the end of vertical colorburst, measured in one less than the
2401+ * number of lines from the start of NBR.
2402+ */
2403+# define TV_VBURST_END_F3_MASK 0x000000ff
2404+# define TV_VBURST_END_F3_SHIFT 0
2405+
2406+#define TV_V_CTL_7 0x68054
2407+/**
2408+ * Offset to start of vertical colorburst, measured in one less than the
2409+ * number of lines from vertical start.
2410+ */
2411+# define TV_VBURST_START_F4_MASK 0x003f0000
2412+# define TV_VBURST_START_F4_SHIFT 16
2413+/**
2414+ * Offset to the end of vertical colorburst, measured in one less than the
2415+ * number of lines from the start of NBR.
2416+ */
2417+# define TV_VBURST_END_F4_MASK 0x000000ff
2418+# define TV_VBURST_END_F4_SHIFT 0
2419+
2420+#define TV_SC_CTL_1 0x68060
2421+/** Turns on the first subcarrier phase generation DDA */
2422+# define TV_SC_DDA1_EN (1 << 31)
2423+/** Turns on the first subcarrier phase generation DDA */
2424+# define TV_SC_DDA2_EN (1 << 30)
2425+/** Turns on the first subcarrier phase generation DDA */
2426+# define TV_SC_DDA3_EN (1 << 29)
2427+/** Sets the subcarrier DDA to reset frequency every other field */
2428+# define TV_SC_RESET_EVERY_2 (0 << 24)
2429+/** Sets the subcarrier DDA to reset frequency every fourth field */
2430+# define TV_SC_RESET_EVERY_4 (1 << 24)
2431+/** Sets the subcarrier DDA to reset frequency every eighth field */
2432+# define TV_SC_RESET_EVERY_8 (2 << 24)
2433+/** Sets the subcarrier DDA to never reset the frequency */
2434+# define TV_SC_RESET_NEVER (3 << 24)
2435+/** Sets the peak amplitude of the colorburst.*/
2436+# define TV_BURST_LEVEL_MASK 0x00ff0000
2437+# define TV_BURST_LEVEL_SHIFT 16
2438+/** Sets the increment of the first subcarrier phase generation DDA */
2439+# define TV_SCDDA1_INC_MASK 0x00000fff
2440+# define TV_SCDDA1_INC_SHIFT 0
2441+
2442+#define TV_SC_CTL_2 0x68064
2443+/** Sets the rollover for the second subcarrier phase generation DDA */
2444+# define TV_SCDDA2_SIZE_MASK 0x7fff0000
2445+# define TV_SCDDA2_SIZE_SHIFT 16
2446+/** Sets the increent of the second subcarrier phase generation DDA */
2447+# define TV_SCDDA2_INC_MASK 0x00007fff
2448+# define TV_SCDDA2_INC_SHIFT 0
2449+
2450+#define TV_SC_CTL_3 0x68068
2451+/** Sets the rollover for the third subcarrier phase generation DDA */
2452+# define TV_SCDDA3_SIZE_MASK 0x7fff0000
2453+# define TV_SCDDA3_SIZE_SHIFT 16
2454+/** Sets the increent of the third subcarrier phase generation DDA */
2455+# define TV_SCDDA3_INC_MASK 0x00007fff
2456+# define TV_SCDDA3_INC_SHIFT 0
2457+
2458+#define TV_WIN_POS 0x68070
2459+/** X coordinate of the display from the start of horizontal active */
2460+# define TV_XPOS_MASK 0x1fff0000
2461+# define TV_XPOS_SHIFT 16
2462+/** Y coordinate of the display from the start of vertical active (NBR) */
2463+# define TV_YPOS_MASK 0x00000fff
2464+# define TV_YPOS_SHIFT 0
2465+
2466+#define TV_WIN_SIZE 0x68074
2467+/** Horizontal size of the display window, measured in pixels*/
2468+# define TV_XSIZE_MASK 0x1fff0000
2469+# define TV_XSIZE_SHIFT 16
2470+/**
2471+ * Vertical size of the display window, measured in pixels.
2472+ *
2473+ * Must be even for interlaced modes.
2474+ */
2475+# define TV_YSIZE_MASK 0x00000fff
2476+# define TV_YSIZE_SHIFT 0
2477+
2478+#define TV_FILTER_CTL_1 0x68080
2479+/**
2480+ * Enables automatic scaling calculation.
2481+ *
2482+ * If set, the rest of the registers are ignored, and the calculated values can
2483+ * be read back from the register.
2484+ */
2485+# define TV_AUTO_SCALE (1 << 31)
2486+/**
2487+ * Disables the vertical filter.
2488+ *
2489+ * This is required on modes more than 1024 pixels wide */
2490+# define TV_V_FILTER_BYPASS (1 << 29)
2491+/** Enables adaptive vertical filtering */
2492+# define TV_VADAPT (1 << 28)
2493+# define TV_VADAPT_MODE_MASK (3 << 26)
2494+/** Selects the least adaptive vertical filtering mode */
2495+# define TV_VADAPT_MODE_LEAST (0 << 26)
2496+/** Selects the moderately adaptive vertical filtering mode */
2497+# define TV_VADAPT_MODE_MODERATE (1 << 26)
2498+/** Selects the most adaptive vertical filtering mode */
2499+# define TV_VADAPT_MODE_MOST (3 << 26)
2500+/**
2501+ * Sets the horizontal scaling factor.
2502+ *
2503+ * This should be the fractional part of the horizontal scaling factor divided
2504+ * by the oversampling rate. TV_HSCALE should be less than 1, and set to:
2505+ *
2506+ * (src width - 1) / ((oversample * dest width) - 1)
2507+ */
2508+# define TV_HSCALE_FRAC_MASK 0x00003fff
2509+# define TV_HSCALE_FRAC_SHIFT 0
2510+
2511+#define TV_FILTER_CTL_2 0x68084
2512+/**
2513+ * Sets the integer part of the 3.15 fixed-point vertical scaling factor.
2514+ *
2515+ * TV_VSCALE should be (src height - 1) / ((interlace * dest height) - 1)
2516+ */
2517+# define TV_VSCALE_INT_MASK 0x00038000
2518+# define TV_VSCALE_INT_SHIFT 15
2519+/**
2520+ * Sets the fractional part of the 3.15 fixed-point vertical scaling factor.
2521+ *
2522+ * \sa TV_VSCALE_INT_MASK
2523+ */
2524+# define TV_VSCALE_FRAC_MASK 0x00007fff
2525+# define TV_VSCALE_FRAC_SHIFT 0
2526+
2527+#define TV_FILTER_CTL_3 0x68088
2528+/**
2529+ * Sets the integer part of the 3.15 fixed-point vertical scaling factor.
2530+ *
2531+ * TV_VSCALE should be (src height - 1) / (1/4 * (dest height - 1))
2532+ *
2533+ * For progressive modes, TV_VSCALE_IP_INT should be set to zeroes.
2534+ */
2535+# define TV_VSCALE_IP_INT_MASK 0x00038000
2536+# define TV_VSCALE_IP_INT_SHIFT 15
2537+/**
2538+ * Sets the fractional part of the 3.15 fixed-point vertical scaling factor.
2539+ *
2540+ * For progressive modes, TV_VSCALE_IP_INT should be set to zeroes.
2541+ *
2542+ * \sa TV_VSCALE_IP_INT_MASK
2543+ */
2544+# define TV_VSCALE_IP_FRAC_MASK 0x00007fff
2545+# define TV_VSCALE_IP_FRAC_SHIFT 0
2546+
2547+#define TV_CC_CONTROL 0x68090
2548+# define TV_CC_ENABLE (1 << 31)
2549+/**
2550+ * Specifies which field to send the CC data in.
2551+ *
2552+ * CC data is usually sent in field 0.
2553+ */
2554+# define TV_CC_FID_MASK (1 << 27)
2555+# define TV_CC_FID_SHIFT 27
2556+/** Sets the horizontal position of the CC data. Usually 135. */
2557+# define TV_CC_HOFF_MASK 0x03ff0000
2558+# define TV_CC_HOFF_SHIFT 16
2559+/** Sets the vertical position of the CC data. Usually 21 */
2560+# define TV_CC_LINE_MASK 0x0000003f
2561+# define TV_CC_LINE_SHIFT 0
2562+
2563+#define TV_CC_DATA 0x68094
2564+# define TV_CC_RDY (1 << 31)
2565+/** Second word of CC data to be transmitted. */
2566+# define TV_CC_DATA_2_MASK 0x007f0000
2567+# define TV_CC_DATA_2_SHIFT 16
2568+/** First word of CC data to be transmitted. */
2569+# define TV_CC_DATA_1_MASK 0x0000007f
2570+# define TV_CC_DATA_1_SHIFT 0
2571+
2572+#define TV_H_LUMA_0 0x68100
2573+#define TV_H_LUMA_59 0x681ec
2574+#define TV_H_CHROMA_0 0x68200
2575+#define TV_H_CHROMA_59 0x682ec
2576+#define TV_V_LUMA_0 0x68300
2577+#define TV_V_LUMA_42 0x683a8
2578+#define TV_V_CHROMA_0 0x68400
2579+#define TV_V_CHROMA_42 0x684a8
2580+
2581+/* Display & cursor control */
2582+
2583+/* Pipe A */
2584+#define PIPEADSL 0x70000
2585+#define PIPEACONF 0x70008
2586+#define PIPEACONF_ENABLE (1<<31)
2587+#define PIPEACONF_DISABLE 0
2588+#define PIPEACONF_DOUBLE_WIDE (1<<30)
2589+#define I965_PIPECONF_ACTIVE (1<<30)
2590+#define PIPEACONF_SINGLE_WIDE 0
2591+#define PIPEACONF_PIPE_UNLOCKED 0
2592+#define PIPEACONF_PIPE_LOCKED (1<<25)
2593+#define PIPEACONF_PALETTE 0
2594+#define PIPEACONF_GAMMA (1<<24)
2595+#define PIPECONF_FORCE_BORDER (1<<25)
2596+#define PIPECONF_PROGRESSIVE (0 << 21)
2597+#define PIPECONF_INTERLACE_W_FIELD_INDICATION (6 << 21)
2598+#define PIPECONF_INTERLACE_FIELD_0_ONLY (7 << 21)
2599+#define PIPEASTAT 0x70024
2600+#define PIPE_FIFO_UNDERRUN_STATUS (1UL<<31)
2601+#define PIPE_CRC_ERROR_ENABLE (1UL<<29)
2602+#define PIPE_CRC_DONE_ENABLE (1UL<<28)
2603+#define PIPE_GMBUS_EVENT_ENABLE (1UL<<27)
2604+#define PIPE_HOTPLUG_INTERRUPT_ENABLE (1UL<<26)
2605+#define PIPE_VSYNC_INTERRUPT_ENABLE (1UL<<25)
2606+#define PIPE_DISPLAY_LINE_COMPARE_ENABLE (1UL<<24)
2607+#define PIPE_DPST_EVENT_ENABLE (1UL<<23)
2608+#define PIPE_LEGACY_BLC_EVENT_ENABLE (1UL<<22)
2609+#define PIPE_ODD_FIELD_INTERRUPT_ENABLE (1UL<<21)
2610+#define PIPE_EVEN_FIELD_INTERRUPT_ENABLE (1UL<<20)
2611+#define PIPE_HOTPLUG_TV_INTERRUPT_ENABLE (1UL<<18) /* pre-965 */
2612+#define PIPE_START_VBLANK_INTERRUPT_ENABLE (1UL<<18) /* 965 or later */
2613+#define PIPE_VBLANK_INTERRUPT_ENABLE (1UL<<17)
2614+#define PIPE_OVERLAY_UPDATED_ENABLE (1UL<<16)
2615+#define PIPE_CRC_ERROR_INTERRUPT_STATUS (1UL<<13)
2616+#define PIPE_CRC_DONE_INTERRUPT_STATUS (1UL<<12)
2617+#define PIPE_GMBUS_INTERRUPT_STATUS (1UL<<11)
2618+#define PIPE_HOTPLUG_INTERRUPT_STATUS (1UL<<10)
2619+#define PIPE_VSYNC_INTERRUPT_STATUS (1UL<<9)
2620+#define PIPE_DISPLAY_LINE_COMPARE_STATUS (1UL<<8)
2621+#define PIPE_DPST_EVENT_STATUS (1UL<<7)
2622+#define PIPE_LEGACY_BLC_EVENT_STATUS (1UL<<6)
2623+#define PIPE_ODD_FIELD_INTERRUPT_STATUS (1UL<<5)
2624+#define PIPE_EVEN_FIELD_INTERRUPT_STATUS (1UL<<4)
2625+#define PIPE_HOTPLUG_TV_INTERRUPT_STATUS (1UL<<2) /* pre-965 */
2626+#define PIPE_START_VBLANK_INTERRUPT_STATUS (1UL<<2) /* 965 or later */
2627+#define PIPE_VBLANK_INTERRUPT_STATUS (1UL<<1)
2628+#define PIPE_OVERLAY_UPDATED_STATUS (1UL<<0)
2629+
2630+#define DSPARB 0x70030
2631+#define DSPARB_CSTART_MASK (0x7f << 7)
2632+#define DSPARB_CSTART_SHIFT 7
2633+#define DSPARB_BSTART_MASK (0x7f)
2634+#define DSPARB_BSTART_SHIFT 0
2635+/*
2636+ * The two pipe frame counter registers are not synchronized, so
2637+ * reading a stable value is somewhat tricky. The following code
2638+ * should work:
2639+ *
2640+ * do {
2641+ * high1 = ((INREG(PIPEAFRAMEHIGH) & PIPE_FRAME_HIGH_MASK) >>
2642+ * PIPE_FRAME_HIGH_SHIFT;
2643+ * low1 = ((INREG(PIPEAFRAMEPIXEL) & PIPE_FRAME_LOW_MASK) >>
2644+ * PIPE_FRAME_LOW_SHIFT);
2645+ * high2 = ((INREG(PIPEAFRAMEHIGH) & PIPE_FRAME_HIGH_MASK) >>
2646+ * PIPE_FRAME_HIGH_SHIFT);
2647+ * } while (high1 != high2);
2648+ * frame = (high1 << 8) | low1;
2649+ */
2650+#define PIPEAFRAMEHIGH 0x70040
2651+#define PIPE_FRAME_HIGH_MASK 0x0000ffff
2652+#define PIPE_FRAME_HIGH_SHIFT 0
2653+#define PIPEAFRAMEPIXEL 0x70044
2654+#define PIPE_FRAME_LOW_MASK 0xff000000
2655+#define PIPE_FRAME_LOW_SHIFT 24
2656+#define PIPE_PIXEL_MASK 0x00ffffff
2657+#define PIPE_PIXEL_SHIFT 0
2658+
2659+/* Cursor A & B regs */
2660+#define CURACNTR 0x70080
2661+#define CURSOR_MODE_DISABLE 0x00
2662+#define CURSOR_MODE_64_32B_AX 0x07
2663+#define CURSOR_MODE_64_ARGB_AX ((1 << 5) | CURSOR_MODE_64_32B_AX)
2664+#define MCURSOR_GAMMA_ENABLE (1 << 26)
2665+#define CURABASE 0x70084
2666+#define CURAPOS 0x70088
2667+#define CURSOR_POS_MASK 0x007FF
2668+#define CURSOR_POS_SIGN 0x8000
2669+#define CURSOR_X_SHIFT 0
2670+#define CURSOR_Y_SHIFT 16
2671+#define CURBCNTR 0x700c0
2672+#define CURBBASE 0x700c4
2673+#define CURBPOS 0x700c8
2674+
2675+/* Display A control */
2676+#define DSPACNTR 0x70180
2677+#define DISPLAY_PLANE_ENABLE (1<<31)
2678+#define DISPLAY_PLANE_DISABLE 0
2679+#define DISPPLANE_GAMMA_ENABLE (1<<30)
2680+#define DISPPLANE_GAMMA_DISABLE 0
2681+#define DISPPLANE_PIXFORMAT_MASK (0xf<<26)
2682+#define DISPPLANE_8BPP (0x2<<26)
2683+#define DISPPLANE_15_16BPP (0x4<<26)
2684+#define DISPPLANE_16BPP (0x5<<26)
2685+#define DISPPLANE_32BPP_NO_ALPHA (0x6<<26)
2686+#define DISPPLANE_32BPP (0x7<<26)
2687+#define DISPPLANE_STEREO_ENABLE (1<<25)
2688+#define DISPPLANE_STEREO_DISABLE 0
2689+#define DISPPLANE_SEL_PIPE_MASK (1<<24)
2690+#define DISPPLANE_SEL_PIPE_A 0
2691+#define DISPPLANE_SEL_PIPE_B (1<<24)
2692+#define DISPPLANE_SRC_KEY_ENABLE (1<<22)
2693+#define DISPPLANE_SRC_KEY_DISABLE 0
2694+#define DISPPLANE_LINE_DOUBLE (1<<20)
2695+#define DISPPLANE_NO_LINE_DOUBLE 0
2696+#define DISPPLANE_STEREO_POLARITY_FIRST 0
2697+#define DISPPLANE_STEREO_POLARITY_SECOND (1<<18)
2698+#define DSPAADDR 0x70184
2699+#define DSPASTRIDE 0x70188
2700+#define DSPAPOS 0x7018C /* reserved */
2701+#define DSPASIZE 0x70190
2702+#define DSPASURF 0x7019C /* 965+ only */
2703+#define DSPATILEOFF 0x701A4 /* 965+ only */
2704+
2705+/* VBIOS flags */
2706+#define SWF00 0x71410
2707+#define SWF01 0x71414
2708+#define SWF02 0x71418
2709+#define SWF03 0x7141c
2710+#define SWF04 0x71420
2711+#define SWF05 0x71424
2712+#define SWF06 0x71428
2713+#define SWF10 0x70410
2714+#define SWF11 0x70414
2715+#define SWF14 0x71420
2716+#define SWF30 0x72414
2717+#define SWF31 0x72418
2718+#define SWF32 0x7241c
2719+
2720+/* Pipe B */
2721+#define PIPEBDSL 0x71000
2722+#define PIPEBCONF 0x71008
2723+#define PIPEBSTAT 0x71024
2724+#define PIPEBFRAMEHIGH 0x71040
2725+#define PIPEBFRAMEPIXEL 0x71044
2726+
2727+/* Display B control */
2728+#define DSPBCNTR 0x71180
2729+#define DISPPLANE_ALPHA_TRANS_ENABLE (1<<15)
2730+#define DISPPLANE_ALPHA_TRANS_DISABLE 0
2731+#define DISPPLANE_SPRITE_ABOVE_DISPLAY 0
2732+#define DISPPLANE_SPRITE_ABOVE_OVERLAY (1)
2733+#define DSPBADDR 0x71184
2734+#define DSPBSTRIDE 0x71188
2735+#define DSPBPOS 0x7118C
2736+#define DSPBSIZE 0x71190
2737+#define DSPBSURF 0x7119C
2738+#define DSPBTILEOFF 0x711A4
2739+
2740+/* VBIOS regs */
2741+#define VGACNTRL 0x71400
2742+# define VGA_DISP_DISABLE (1 << 31)
2743+# define VGA_2X_MODE (1 << 30)
2744+# define VGA_PIPE_B_SELECT (1 << 29)
2745+
2746+#endif /* _I915_REG_H_ */
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27/0005-i915-Add-support-for-MSI-and-interrupt-mitigation.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27/0005-i915-Add-support-for-MSI-and-interrupt-mitigation.patch
new file mode 100644
index 0000000000..9337475c31
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27/0005-i915-Add-support-for-MSI-and-interrupt-mitigation.patch
@@ -0,0 +1,424 @@
1commit 4f99970852559935b27bc634318f34c18c5fd143
2Author: Eric Anholt <eric@anholt.net>
3Date: Tue Jul 29 12:10:39 2008 -0700
4
5 i915: Add support for MSI and interrupt mitigation.
6
7 Previous attempts at interrupt mitigation had been foiled by i915_wait_irq's
8 failure to update the sarea seqno value when the status page indicated that
9 the seqno had already been passed. MSI support has been seen to cut CPU
10 costs by up to 40% in some workloads by avoiding other expensive interrupt
11 handlers for frequent graphics interrupts.
12
13 Signed-off-by: Eric Anholt <eric@anholt.net>
14 Signed-off-by: Dave Airlie <airlied@redhat.com>
15
16diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
17index 53f0e5a..61ed515 100644
18--- a/drivers/gpu/drm/drm_irq.c
19+++ b/drivers/gpu/drm/drm_irq.c
20@@ -63,7 +63,7 @@ int drm_irq_by_busid(struct drm_device *dev, void *data,
21 p->devnum != PCI_SLOT(dev->pdev->devfn) || p->funcnum != PCI_FUNC(dev->pdev->devfn))
22 return -EINVAL;
23
24- p->irq = dev->irq;
25+ p->irq = dev->pdev->irq;
26
27 DRM_DEBUG("%d:%d:%d => IRQ %d\n", p->busnum, p->devnum, p->funcnum,
28 p->irq);
29@@ -89,7 +89,7 @@ static int drm_irq_install(struct drm_device * dev)
30 if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
31 return -EINVAL;
32
33- if (dev->irq == 0)
34+ if (dev->pdev->irq == 0)
35 return -EINVAL;
36
37 mutex_lock(&dev->struct_mutex);
38@@ -107,7 +107,7 @@ static int drm_irq_install(struct drm_device * dev)
39 dev->irq_enabled = 1;
40 mutex_unlock(&dev->struct_mutex);
41
42- DRM_DEBUG("irq=%d\n", dev->irq);
43+ DRM_DEBUG("irq=%d\n", dev->pdev->irq);
44
45 if (drm_core_check_feature(dev, DRIVER_IRQ_VBL)) {
46 init_waitqueue_head(&dev->vbl_queue);
47@@ -127,8 +127,12 @@ static int drm_irq_install(struct drm_device * dev)
48 if (drm_core_check_feature(dev, DRIVER_IRQ_SHARED))
49 sh_flags = IRQF_SHARED;
50
51- ret = request_irq(dev->irq, dev->driver->irq_handler,
52+ ret = request_irq(dev->pdev->irq, dev->driver->irq_handler,
53 sh_flags, dev->devname, dev);
54+ /* Expose the device irq number to drivers that want to export it for
55+ * whatever reason.
56+ */
57+ dev->irq = dev->pdev->irq;
58 if (ret < 0) {
59 mutex_lock(&dev->struct_mutex);
60 dev->irq_enabled = 0;
61@@ -164,11 +168,11 @@ int drm_irq_uninstall(struct drm_device * dev)
62 if (!irq_enabled)
63 return -EINVAL;
64
65- DRM_DEBUG("irq=%d\n", dev->irq);
66+ DRM_DEBUG("irq=%d\n", dev->pdev->irq);
67
68 dev->driver->irq_uninstall(dev);
69
70- free_irq(dev->irq, dev);
71+ free_irq(dev->pdev->irq, dev);
72
73 dev->locked_tasklet_func = NULL;
74
75@@ -201,7 +205,7 @@ int drm_control(struct drm_device *dev, void *data,
76 if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
77 return 0;
78 if (dev->if_version < DRM_IF_VERSION(1, 2) &&
79- ctl->irq != dev->irq)
80+ ctl->irq != dev->pdev->irq)
81 return -EINVAL;
82 return drm_irq_install(dev);
83 case DRM_UNINST_HANDLER:
84@@ -239,7 +243,7 @@ int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_pr
85 int ret = 0;
86 unsigned int flags, seq;
87
88- if ((!dev->irq) || (!dev->irq_enabled))
89+ if ((!dev->pdev->irq) || (!dev->irq_enabled))
90 return -EINVAL;
91
92 if (vblwait->request.type &
93diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
94index 7be580b..10bfb0c 100644
95--- a/drivers/gpu/drm/i915/i915_dma.c
96+++ b/drivers/gpu/drm/i915/i915_dma.c
97@@ -84,7 +84,7 @@ static int i915_dma_cleanup(struct drm_device * dev)
98 * may not have been called from userspace and after dev_private
99 * is freed, it's too late.
100 */
101- if (dev->irq)
102+ if (dev->irq_enabled)
103 drm_irq_uninstall(dev);
104
105 if (dev_priv->ring.virtual_start) {
106@@ -644,7 +644,7 @@ static int i915_getparam(struct drm_device *dev, void *data,
107
108 switch (param->param) {
109 case I915_PARAM_IRQ_ACTIVE:
110- value = dev->irq ? 1 : 0;
111+ value = dev->irq_enabled;
112 break;
113 case I915_PARAM_ALLOW_BATCHBUFFER:
114 value = dev_priv->allow_batchbuffer ? 1 : 0;
115@@ -763,6 +763,20 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
116 ret = drm_addmap(dev, base, size, _DRM_REGISTERS,
117 _DRM_KERNEL | _DRM_DRIVER,
118 &dev_priv->mmio_map);
119+
120+
121+ /* On the 945G/GM, the chipset reports the MSI capability on the
122+ * integrated graphics even though the support isn't actually there
123+ * according to the published specs. It doesn't appear to function
124+ * correctly in testing on 945G.
125+ * This may be a side effect of MSI having been made available for PEG
126+ * and the registers being closely associated.
127+ */
128+ if (!IS_I945G(dev) && !IS_I945GM(dev))
129+ pci_enable_msi(dev->pdev);
130+
131+ spin_lock_init(&dev_priv->user_irq_lock);
132+
133 return ret;
134 }
135
136@@ -770,6 +784,9 @@ int i915_driver_unload(struct drm_device *dev)
137 {
138 struct drm_i915_private *dev_priv = dev->dev_private;
139
140+ if (dev->pdev->msi_enabled)
141+ pci_disable_msi(dev->pdev);
142+
143 if (dev_priv->mmio_map)
144 drm_rmmap(dev, dev_priv->mmio_map);
145
146diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
147index afb51a3..8daf0d8 100644
148--- a/drivers/gpu/drm/i915/i915_drv.h
149+++ b/drivers/gpu/drm/i915/i915_drv.h
150@@ -105,6 +105,12 @@ typedef struct drm_i915_private {
151 wait_queue_head_t irq_queue;
152 atomic_t irq_received;
153 atomic_t irq_emitted;
154+ /** Protects user_irq_refcount and irq_mask_reg */
155+ spinlock_t user_irq_lock;
156+ /** Refcount for i915_user_irq_get() versus i915_user_irq_put(). */
157+ int user_irq_refcount;
158+ /** Cached value of IMR to avoid reads in updating the bitfield */
159+ u32 irq_mask_reg;
160
161 int tex_lru_log_granularity;
162 int allow_batchbuffer;
163diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
164index 4a2de78..24d11ed 100644
165--- a/drivers/gpu/drm/i915/i915_irq.c
166+++ b/drivers/gpu/drm/i915/i915_irq.c
167@@ -33,6 +33,31 @@
168
169 #define MAX_NOPID ((u32)~0)
170
171+/** These are the interrupts used by the driver */
172+#define I915_INTERRUPT_ENABLE_MASK (I915_USER_INTERRUPT | \
173+ I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT | \
174+ I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT)
175+
176+static inline void
177+i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask)
178+{
179+ if ((dev_priv->irq_mask_reg & mask) != 0) {
180+ dev_priv->irq_mask_reg &= ~mask;
181+ I915_WRITE(IMR, dev_priv->irq_mask_reg);
182+ (void) I915_READ(IMR);
183+ }
184+}
185+
186+static inline void
187+i915_disable_irq(drm_i915_private_t *dev_priv, u32 mask)
188+{
189+ if ((dev_priv->irq_mask_reg & mask) != mask) {
190+ dev_priv->irq_mask_reg |= mask;
191+ I915_WRITE(IMR, dev_priv->irq_mask_reg);
192+ (void) I915_READ(IMR);
193+ }
194+}
195+
196 /**
197 * Emit blits for scheduled buffer swaps.
198 *
199@@ -229,46 +254,50 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
200 {
201 struct drm_device *dev = (struct drm_device *) arg;
202 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
203- u16 temp;
204 u32 pipea_stats, pipeb_stats;
205+ u32 iir;
206
207 pipea_stats = I915_READ(PIPEASTAT);
208 pipeb_stats = I915_READ(PIPEBSTAT);
209
210- temp = I915_READ16(IIR);
211-
212- temp &= (I915_USER_INTERRUPT |
213- I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT |
214- I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT);
215+ if (dev->pdev->msi_enabled)
216+ I915_WRITE(IMR, ~0);
217+ iir = I915_READ(IIR);
218
219- DRM_DEBUG("%s flag=%08x\n", __FUNCTION__, temp);
220+ DRM_DEBUG("iir=%08x\n", iir);
221
222- if (temp == 0)
223+ if (iir == 0) {
224+ if (dev->pdev->msi_enabled) {
225+ I915_WRITE(IMR, dev_priv->irq_mask_reg);
226+ (void) I915_READ(IMR);
227+ }
228 return IRQ_NONE;
229+ }
230
231- I915_WRITE16(IIR, temp);
232- (void) I915_READ16(IIR);
233- DRM_READMEMORYBARRIER();
234+ I915_WRITE(IIR, iir);
235+ if (dev->pdev->msi_enabled)
236+ I915_WRITE(IMR, dev_priv->irq_mask_reg);
237+ (void) I915_READ(IIR); /* Flush posted writes */
238
239 dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
240
241- if (temp & I915_USER_INTERRUPT)
242+ if (iir & I915_USER_INTERRUPT)
243 DRM_WAKEUP(&dev_priv->irq_queue);
244
245- if (temp & (I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT |
246- I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT)) {
247+ if (iir & (I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT |
248+ I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT)) {
249 int vblank_pipe = dev_priv->vblank_pipe;
250
251 if ((vblank_pipe &
252 (DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B))
253 == (DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B)) {
254- if (temp & I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT)
255+ if (iir & I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT)
256 atomic_inc(&dev->vbl_received);
257- if (temp & I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT)
258+ if (iir & I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT)
259 atomic_inc(&dev->vbl_received2);
260- } else if (((temp & I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT) &&
261+ } else if (((iir & I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT) &&
262 (vblank_pipe & DRM_I915_VBLANK_PIPE_A)) ||
263- ((temp & I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT) &&
264+ ((iir & I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT) &&
265 (vblank_pipe & DRM_I915_VBLANK_PIPE_B)))
266 atomic_inc(&dev->vbl_received);
267
268@@ -314,6 +343,27 @@ static int i915_emit_irq(struct drm_device * dev)
269 return dev_priv->counter;
270 }
271
272+static void i915_user_irq_get(struct drm_device *dev)
273+{
274+ drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
275+
276+ spin_lock(&dev_priv->user_irq_lock);
277+ if (dev->irq_enabled && (++dev_priv->user_irq_refcount == 1))
278+ i915_enable_irq(dev_priv, I915_USER_INTERRUPT);
279+ spin_unlock(&dev_priv->user_irq_lock);
280+}
281+
282+static void i915_user_irq_put(struct drm_device *dev)
283+{
284+ drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
285+
286+ spin_lock(&dev_priv->user_irq_lock);
287+ BUG_ON(dev->irq_enabled && dev_priv->user_irq_refcount <= 0);
288+ if (dev->irq_enabled && (--dev_priv->user_irq_refcount == 0))
289+ i915_disable_irq(dev_priv, I915_USER_INTERRUPT);
290+ spin_unlock(&dev_priv->user_irq_lock);
291+}
292+
293 static int i915_wait_irq(struct drm_device * dev, int irq_nr)
294 {
295 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
296@@ -322,13 +372,17 @@ static int i915_wait_irq(struct drm_device * dev, int irq_nr)
297 DRM_DEBUG("irq_nr=%d breadcrumb=%d\n", irq_nr,
298 READ_BREADCRUMB(dev_priv));
299
300- if (READ_BREADCRUMB(dev_priv) >= irq_nr)
301+ if (READ_BREADCRUMB(dev_priv) >= irq_nr) {
302+ dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
303 return 0;
304+ }
305
306 dev_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT;
307
308+ i915_user_irq_get(dev);
309 DRM_WAIT_ON(ret, dev_priv->irq_queue, 3 * DRM_HZ,
310 READ_BREADCRUMB(dev_priv) >= irq_nr);
311+ i915_user_irq_put(dev);
312
313 if (ret == -EBUSY) {
314 DRM_ERROR("EBUSY -- rec: %d emitted: %d\n",
315@@ -413,20 +467,6 @@ int i915_irq_wait(struct drm_device *dev, void *data,
316 return i915_wait_irq(dev, irqwait->irq_seq);
317 }
318
319-static void i915_enable_interrupt (struct drm_device *dev)
320-{
321- drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
322- u16 flag;
323-
324- flag = 0;
325- if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_A)
326- flag |= I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT;
327- if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_B)
328- flag |= I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
329-
330- I915_WRITE16(IER, I915_USER_INTERRUPT | flag);
331-}
332-
333 /* Set the vblank monitor pipe
334 */
335 int i915_vblank_pipe_set(struct drm_device *dev, void *data,
336@@ -434,6 +474,7 @@ int i915_vblank_pipe_set(struct drm_device *dev, void *data,
337 {
338 drm_i915_private_t *dev_priv = dev->dev_private;
339 drm_i915_vblank_pipe_t *pipe = data;
340+ u32 enable_mask = 0, disable_mask = 0;
341
342 if (!dev_priv) {
343 DRM_ERROR("called with no initialization\n");
344@@ -445,9 +486,20 @@ int i915_vblank_pipe_set(struct drm_device *dev, void *data,
345 return -EINVAL;
346 }
347
348- dev_priv->vblank_pipe = pipe->pipe;
349+ if (pipe->pipe & DRM_I915_VBLANK_PIPE_A)
350+ enable_mask |= I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT;
351+ else
352+ disable_mask |= I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT;
353+
354+ if (pipe->pipe & DRM_I915_VBLANK_PIPE_B)
355+ enable_mask |= I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
356+ else
357+ disable_mask |= I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
358
359- i915_enable_interrupt (dev);
360+ i915_enable_irq(dev_priv, enable_mask);
361+ i915_disable_irq(dev_priv, disable_mask);
362+
363+ dev_priv->vblank_pipe = pipe->pipe;
364
365 return 0;
366 }
367@@ -464,7 +516,7 @@ int i915_vblank_pipe_get(struct drm_device *dev, void *data,
368 return -EINVAL;
369 }
370
371- flag = I915_READ(IER);
372+ flag = I915_READ(IMR);
373 pipe->pipe = 0;
374 if (flag & I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT)
375 pipe->pipe |= DRM_I915_VBLANK_PIPE_A;
376@@ -586,9 +638,9 @@ void i915_driver_irq_preinstall(struct drm_device * dev)
377 {
378 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
379
380- I915_WRITE16(HWSTAM, 0xfffe);
381- I915_WRITE16(IMR, 0x0);
382- I915_WRITE16(IER, 0x0);
383+ I915_WRITE(HWSTAM, 0xfffe);
384+ I915_WRITE(IMR, 0x0);
385+ I915_WRITE(IER, 0x0);
386 }
387
388 void i915_driver_irq_postinstall(struct drm_device * dev)
389@@ -601,7 +653,18 @@ void i915_driver_irq_postinstall(struct drm_device * dev)
390
391 if (!dev_priv->vblank_pipe)
392 dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A;
393- i915_enable_interrupt(dev);
394+
395+ /* Set initial unmasked IRQs to just the selected vblank pipes. */
396+ dev_priv->irq_mask_reg = ~0;
397+ if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_A)
398+ dev_priv->irq_mask_reg &= ~I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT;
399+ if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_B)
400+ dev_priv->irq_mask_reg &= ~I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
401+
402+ I915_WRITE(IMR, dev_priv->irq_mask_reg);
403+ I915_WRITE(IER, I915_INTERRUPT_ENABLE_MASK);
404+ (void) I915_READ(IER);
405+
406 DRM_INIT_WAITQUEUE(&dev_priv->irq_queue);
407 }
408
409@@ -613,10 +676,10 @@ void i915_driver_irq_uninstall(struct drm_device * dev)
410 if (!dev_priv)
411 return;
412
413- I915_WRITE16(HWSTAM, 0xffff);
414- I915_WRITE16(IMR, 0xffff);
415- I915_WRITE16(IER, 0x0);
416+ I915_WRITE(HWSTAM, 0xffff);
417+ I915_WRITE(IMR, 0xffff);
418+ I915_WRITE(IER, 0x0);
419
420- temp = I915_READ16(IIR);
421- I915_WRITE16(IIR, temp);
422+ temp = I915_READ(IIR);
423+ I915_WRITE(IIR, temp);
424 }
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27/0006-i915-Track-progress-inside-of-batchbuffers-for-dete.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27/0006-i915-Track-progress-inside-of-batchbuffers-for-dete.patch
new file mode 100644
index 0000000000..8736250f00
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27/0006-i915-Track-progress-inside-of-batchbuffers-for-dete.patch
@@ -0,0 +1,46 @@
1commit 1236e8610ab9c6f9f8297e60530bedb2640c7224
2Author: Keith Packard <keithp@keithp.com>
3Date: Wed Jul 30 12:21:20 2008 -0700
4
5 i915: Track progress inside of batchbuffers for determining wedgedness.
6
7 This avoids early termination for long-running commands.
8
9 Signed-off-by: Eric Anholt <eric@anholt.net>
10 Signed-off-by: Dave Airlie <airlied@redhat.com>
11
12diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
13index 10bfb0c..4c72a01 100644
14--- a/drivers/gpu/drm/i915/i915_dma.c
15+++ b/drivers/gpu/drm/i915/i915_dma.c
16@@ -40,11 +40,15 @@ int i915_wait_ring(struct drm_device * dev, int n, const char *caller)
17 {
18 drm_i915_private_t *dev_priv = dev->dev_private;
19 drm_i915_ring_buffer_t *ring = &(dev_priv->ring);
20+ u32 acthd_reg = IS_I965G(dev) ? ACTHD_I965 : ACTHD;
21+ u32 last_acthd = I915_READ(acthd_reg);
22+ u32 acthd;
23 u32 last_head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
24 int i;
25
26- for (i = 0; i < 10000; i++) {
27+ for (i = 0; i < 100000; i++) {
28 ring->head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
29+ acthd = I915_READ(acthd_reg);
30 ring->space = ring->head - (ring->tail + 8);
31 if (ring->space < 0)
32 ring->space += ring->Size;
33@@ -55,8 +59,13 @@ int i915_wait_ring(struct drm_device * dev, int n, const char *caller)
34
35 if (ring->head != last_head)
36 i = 0;
37+ if (acthd != last_acthd)
38+ i = 0;
39
40 last_head = ring->head;
41+ last_acthd = acthd;
42+ msleep_interruptible(10);
43+
44 }
45
46 return -EBUSY;
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27/0007-i915-Initialize-hardware-status-page-at-device-load.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27/0007-i915-Initialize-hardware-status-page-at-device-load.patch
new file mode 100644
index 0000000000..79f068f422
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27/0007-i915-Initialize-hardware-status-page-at-device-load.patch
@@ -0,0 +1,137 @@
1commit 75fed4ae8454aa975c274b2585ec2287dd15773d
2Author: Keith Packard <keithp@keithp.com>
3Date: Wed Jul 30 13:03:43 2008 -0700
4
5 i915: Initialize hardware status page at device load when possible.
6
7 Some chips were unstable with repeated setup/teardown of the hardware status
8 page.
9
10 Signed-off-by: Eric Anholt <eric@anholt.net>
11 Signed-off-by: Dave Airlie <airlied@redhat.com>
12
13diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
14index 4c72a01..b3c4ac9 100644
15--- a/drivers/gpu/drm/i915/i915_dma.c
16+++ b/drivers/gpu/drm/i915/i915_dma.c
17@@ -71,6 +71,52 @@ int i915_wait_ring(struct drm_device * dev, int n, const char *caller)
18 return -EBUSY;
19 }
20
21+/**
22+ * Sets up the hardware status page for devices that need a physical address
23+ * in the register.
24+ */
25+int i915_init_phys_hws(struct drm_device *dev)
26+{
27+ drm_i915_private_t *dev_priv = dev->dev_private;
28+ /* Program Hardware Status Page */
29+ dev_priv->status_page_dmah =
30+ drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 0xffffffff);
31+
32+ if (!dev_priv->status_page_dmah) {
33+ DRM_ERROR("Can not allocate hardware status page\n");
34+ return -ENOMEM;
35+ }
36+ dev_priv->hw_status_page = dev_priv->status_page_dmah->vaddr;
37+ dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr;
38+
39+ memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
40+
41+ I915_WRITE(HWS_PGA, dev_priv->dma_status_page);
42+ DRM_DEBUG("Enabled hardware status page\n");
43+ return 0;
44+}
45+
46+/**
47+ * Frees the hardware status page, whether it's a physical address or a virtual
48+ * address set up by the X Server.
49+ */
50+void i915_free_hws(struct drm_device *dev)
51+{
52+ drm_i915_private_t *dev_priv = dev->dev_private;
53+ if (dev_priv->status_page_dmah) {
54+ drm_pci_free(dev, dev_priv->status_page_dmah);
55+ dev_priv->status_page_dmah = NULL;
56+ }
57+
58+ if (dev_priv->status_gfx_addr) {
59+ dev_priv->status_gfx_addr = 0;
60+ drm_core_ioremapfree(&dev_priv->hws_map, dev);
61+ }
62+
63+ /* Need to rewrite hardware status page */
64+ I915_WRITE(HWS_PGA, 0x1ffff000);
65+}
66+
67 void i915_kernel_lost_context(struct drm_device * dev)
68 {
69 drm_i915_private_t *dev_priv = dev->dev_private;
70@@ -103,18 +149,9 @@ static int i915_dma_cleanup(struct drm_device * dev)
71 dev_priv->ring.map.size = 0;
72 }
73
74- if (dev_priv->status_page_dmah) {
75- drm_pci_free(dev, dev_priv->status_page_dmah);
76- dev_priv->status_page_dmah = NULL;
77- /* Need to rewrite hardware status page */
78- I915_WRITE(HWS_PGA, 0x1ffff000);
79- }
80-
81- if (dev_priv->status_gfx_addr) {
82- dev_priv->status_gfx_addr = 0;
83- drm_core_ioremapfree(&dev_priv->hws_map, dev);
84- I915_WRITE(HWS_PGA, 0x1ffff000);
85- }
86+ /* Clear the HWS virtual address at teardown */
87+ if (I915_NEED_GFX_HWS(dev))
88+ i915_free_hws(dev);
89
90 return 0;
91 }
92@@ -165,23 +202,6 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
93 */
94 dev_priv->allow_batchbuffer = 1;
95
96- /* Program Hardware Status Page */
97- if (!I915_NEED_GFX_HWS(dev)) {
98- dev_priv->status_page_dmah =
99- drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 0xffffffff);
100-
101- if (!dev_priv->status_page_dmah) {
102- i915_dma_cleanup(dev);
103- DRM_ERROR("Can not allocate hardware status page\n");
104- return -ENOMEM;
105- }
106- dev_priv->hw_status_page = dev_priv->status_page_dmah->vaddr;
107- dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr;
108-
109- memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
110- I915_WRITE(HWS_PGA, dev_priv->dma_status_page);
111- }
112- DRM_DEBUG("Enabled hardware status page\n");
113 return 0;
114 }
115
116@@ -773,6 +793,12 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
117 _DRM_KERNEL | _DRM_DRIVER,
118 &dev_priv->mmio_map);
119
120+ /* Init HWS */
121+ if (!I915_NEED_GFX_HWS(dev)) {
122+ ret = i915_init_phys_hws(dev);
123+ if (ret != 0)
124+ return ret;
125+ }
126
127 /* On the 945G/GM, the chipset reports the MSI capability on the
128 * integrated graphics even though the support isn't actually there
129@@ -796,6 +822,8 @@ int i915_driver_unload(struct drm_device *dev)
130 if (dev->pdev->msi_enabled)
131 pci_disable_msi(dev->pdev);
132
133+ i915_free_hws(dev);
134+
135 if (dev_priv->mmio_map)
136 drm_rmmap(dev, dev_priv->mmio_map);
137
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27/0008-Add-Intel-ACPI-IGD-OpRegion-support.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27/0008-Add-Intel-ACPI-IGD-OpRegion-support.patch
new file mode 100644
index 0000000000..afa6f96345
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27/0008-Add-Intel-ACPI-IGD-OpRegion-support.patch
@@ -0,0 +1,572 @@
1commit 91c2ebb8e78aa64f4807399b506ec0090ae5f3d6
2Author: Matthew Garrett <mjg59@srcf.ucam.org>
3Date: Tue Aug 5 19:37:25 2008 +0100
4
5 Add Intel ACPI IGD OpRegion support
6
7 This adds the support necessary for allowing ACPI backlight control to
8 work on some newer Intel-based graphics systems. Tested on Thinkpad T61
9 and HP 2510p hardware.
10
11 Signed-off-by: Matthew Garrett <mjg@redhat.com>
12 Signed-off-by: Dave Airlie <airlied@linux.ie>
13
14diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
15index a9e6046..b032808 100644
16--- a/drivers/gpu/drm/i915/Makefile
17+++ b/drivers/gpu/drm/i915/Makefile
18@@ -3,7 +3,7 @@
19 # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
20
21 ccflags-y := -Iinclude/drm
22-i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o
23+i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o i915_opregion.o
24
25 i915-$(CONFIG_COMPAT) += i915_ioc32.o
26
27diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
28index b3c4ac9..cead62f 100644
29--- a/drivers/gpu/drm/i915/i915_dma.c
30+++ b/drivers/gpu/drm/i915/i915_dma.c
31@@ -810,6 +810,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
32 if (!IS_I945G(dev) && !IS_I945GM(dev))
33 pci_enable_msi(dev->pdev);
34
35+ intel_opregion_init(dev);
36+
37 spin_lock_init(&dev_priv->user_irq_lock);
38
39 return ret;
40@@ -827,6 +829,8 @@ int i915_driver_unload(struct drm_device *dev)
41 if (dev_priv->mmio_map)
42 drm_rmmap(dev, dev_priv->mmio_map);
43
44+ intel_opregion_free(dev);
45+
46 drm_free(dev->dev_private, sizeof(drm_i915_private_t),
47 DRM_MEM_DRIVER);
48
49diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
50index 6c99aab..d95eca2 100644
51--- a/drivers/gpu/drm/i915/i915_drv.c
52+++ b/drivers/gpu/drm/i915/i915_drv.c
53@@ -371,6 +371,8 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state)
54
55 i915_save_vga(dev);
56
57+ intel_opregion_free(dev);
58+
59 if (state.event == PM_EVENT_SUSPEND) {
60 /* Shut down the device */
61 pci_disable_device(dev->pdev);
62@@ -532,6 +534,8 @@ static int i915_resume(struct drm_device *dev)
63
64 i915_restore_vga(dev);
65
66+ intel_opregion_init(dev);
67+
68 return 0;
69 }
70
71diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
72index 8daf0d8..e4bd01c 100644
73--- a/drivers/gpu/drm/i915/i915_drv.h
74+++ b/drivers/gpu/drm/i915/i915_drv.h
75@@ -82,6 +82,14 @@ typedef struct _drm_i915_vbl_swap {
76 unsigned int sequence;
77 } drm_i915_vbl_swap_t;
78
79+struct intel_opregion {
80+ struct opregion_header *header;
81+ struct opregion_acpi *acpi;
82+ struct opregion_swsci *swsci;
83+ struct opregion_asle *asle;
84+ int enabled;
85+};
86+
87 typedef struct drm_i915_private {
88 drm_local_map_t *sarea;
89 drm_local_map_t *mmio_map;
90@@ -122,6 +130,8 @@ typedef struct drm_i915_private {
91 drm_i915_vbl_swap_t vbl_swaps;
92 unsigned int swaps_pending;
93
94+ struct intel_opregion opregion;
95+
96 /* Register state */
97 u8 saveLBB;
98 u32 saveDSPACNTR;
99@@ -244,6 +254,7 @@ extern int i915_vblank_pipe_get(struct drm_device *dev, void *data,
100 struct drm_file *file_priv);
101 extern int i915_vblank_swap(struct drm_device *dev, void *data,
102 struct drm_file *file_priv);
103+extern void i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask);
104
105 /* i915_mem.c */
106 extern int i915_mem_alloc(struct drm_device *dev, void *data,
107@@ -258,6 +269,12 @@ extern void i915_mem_takedown(struct mem_block **heap);
108 extern void i915_mem_release(struct drm_device * dev,
109 struct drm_file *file_priv, struct mem_block *heap);
110
111+/* i915_opregion.c */
112+extern int intel_opregion_init(struct drm_device *dev);
113+extern void intel_opregion_free(struct drm_device *dev);
114+extern void opregion_asle_intr(struct drm_device *dev);
115+extern void opregion_enable_asle(struct drm_device *dev);
116+
117 #define I915_READ(reg) DRM_READ32(dev_priv->mmio_map, (reg))
118 #define I915_WRITE(reg,val) DRM_WRITE32(dev_priv->mmio_map, (reg), (val))
119 #define I915_READ16(reg) DRM_READ16(dev_priv->mmio_map, (reg))
120diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
121index 24d11ed..ae7d3a8 100644
122--- a/drivers/gpu/drm/i915/i915_irq.c
123+++ b/drivers/gpu/drm/i915/i915_irq.c
124@@ -36,9 +36,11 @@
125 /** These are the interrupts used by the driver */
126 #define I915_INTERRUPT_ENABLE_MASK (I915_USER_INTERRUPT | \
127 I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT | \
128- I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT)
129+ I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT | \
130+ I915_ASLE_INTERRUPT | \
131+ I915_DISPLAY_PIPE_B_EVENT_INTERRUPT)
132
133-static inline void
134+void
135 i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask)
136 {
137 if ((dev_priv->irq_mask_reg & mask) != 0) {
138@@ -274,6 +276,9 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
139 return IRQ_NONE;
140 }
141
142+ I915_WRITE(PIPEASTAT, pipea_stats);
143+ I915_WRITE(PIPEBSTAT, pipeb_stats);
144+
145 I915_WRITE(IIR, iir);
146 if (dev->pdev->msi_enabled)
147 I915_WRITE(IMR, dev_priv->irq_mask_reg);
148@@ -306,14 +311,14 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
149
150 if (dev_priv->swaps_pending > 0)
151 drm_locked_tasklet(dev, i915_vblank_tasklet);
152- I915_WRITE(PIPEASTAT,
153- pipea_stats|I915_VBLANK_INTERRUPT_ENABLE|
154- PIPE_VBLANK_INTERRUPT_STATUS);
155- I915_WRITE(PIPEBSTAT,
156- pipeb_stats|I915_VBLANK_INTERRUPT_ENABLE|
157- PIPE_VBLANK_INTERRUPT_STATUS);
158 }
159
160+ if (iir & I915_ASLE_INTERRUPT)
161+ opregion_asle_intr(dev);
162+
163+ if (iir & I915_DISPLAY_PIPE_B_EVENT_INTERRUPT)
164+ opregion_asle_intr(dev);
165+
166 return IRQ_HANDLED;
167 }
168
169@@ -661,10 +666,14 @@ void i915_driver_irq_postinstall(struct drm_device * dev)
170 if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_B)
171 dev_priv->irq_mask_reg &= ~I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
172
173+ dev_priv->irq_mask_reg &= I915_INTERRUPT_ENABLE_MASK;
174+
175 I915_WRITE(IMR, dev_priv->irq_mask_reg);
176 I915_WRITE(IER, I915_INTERRUPT_ENABLE_MASK);
177 (void) I915_READ(IER);
178
179+ opregion_enable_asle(dev);
180+
181 DRM_INIT_WAITQUEUE(&dev_priv->irq_queue);
182 }
183
184diff --git a/drivers/gpu/drm/i915/i915_opregion.c b/drivers/gpu/drm/i915/i915_opregion.c
185new file mode 100644
186index 0000000..1787a0c
187--- /dev/null
188+++ b/drivers/gpu/drm/i915/i915_opregion.c
189@@ -0,0 +1,371 @@
190+/*
191+ * Copyright 2008 Intel Corporation <hong.liu@intel.com>
192+ * Copyright 2008 Red Hat <mjg@redhat.com>
193+ *
194+ * Permission is hereby granted, free of charge, to any person obtaining
195+ * a copy of this software and associated documentation files (the
196+ * "Software"), to deal in the Software without restriction, including
197+ * without limitation the rights to use, copy, modify, merge, publish,
198+ * distribute, sub license, and/or sell copies of the Software, and to
199+ * permit persons to whom the Software is furnished to do so, subject to
200+ * the following conditions:
201+ *
202+ * The above copyright notice and this permission notice (including the
203+ * next paragraph) shall be included in all copies or substantial
204+ * portions of the Software.
205+ *
206+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
207+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
208+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
209+ * NON-INFRINGEMENT. IN NO EVENT SHALL INTEL AND/OR ITS SUPPLIERS BE
210+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
211+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
212+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
213+ * SOFTWARE.
214+ *
215+ */
216+
217+#include <linux/acpi.h>
218+
219+#include "drmP.h"
220+#include "i915_drm.h"
221+#include "i915_drv.h"
222+
223+#define PCI_ASLE 0xe4
224+#define PCI_LBPC 0xf4
225+#define PCI_ASLS 0xfc
226+
227+#define OPREGION_SZ (8*1024)
228+#define OPREGION_HEADER_OFFSET 0
229+#define OPREGION_ACPI_OFFSET 0x100
230+#define OPREGION_SWSCI_OFFSET 0x200
231+#define OPREGION_ASLE_OFFSET 0x300
232+#define OPREGION_VBT_OFFSET 0x1000
233+
234+#define OPREGION_SIGNATURE "IntelGraphicsMem"
235+#define MBOX_ACPI (1<<0)
236+#define MBOX_SWSCI (1<<1)
237+#define MBOX_ASLE (1<<2)
238+
239+struct opregion_header {
240+ u8 signature[16];
241+ u32 size;
242+ u32 opregion_ver;
243+ u8 bios_ver[32];
244+ u8 vbios_ver[16];
245+ u8 driver_ver[16];
246+ u32 mboxes;
247+ u8 reserved[164];
248+} __attribute__((packed));
249+
250+/* OpRegion mailbox #1: public ACPI methods */
251+struct opregion_acpi {
252+ u32 drdy; /* driver readiness */
253+ u32 csts; /* notification status */
254+ u32 cevt; /* current event */
255+ u8 rsvd1[20];
256+ u32 didl[8]; /* supported display devices ID list */
257+ u32 cpdl[8]; /* currently presented display list */
258+ u32 cadl[8]; /* currently active display list */
259+ u32 nadl[8]; /* next active devices list */
260+ u32 aslp; /* ASL sleep time-out */
261+ u32 tidx; /* toggle table index */
262+ u32 chpd; /* current hotplug enable indicator */
263+ u32 clid; /* current lid state*/
264+ u32 cdck; /* current docking state */
265+ u32 sxsw; /* Sx state resume */
266+ u32 evts; /* ASL supported events */
267+ u32 cnot; /* current OS notification */
268+ u32 nrdy; /* driver status */
269+ u8 rsvd2[60];
270+} __attribute__((packed));
271+
272+/* OpRegion mailbox #2: SWSCI */
273+struct opregion_swsci {
274+ u32 scic; /* SWSCI command|status|data */
275+ u32 parm; /* command parameters */
276+ u32 dslp; /* driver sleep time-out */
277+ u8 rsvd[244];
278+} __attribute__((packed));
279+
280+/* OpRegion mailbox #3: ASLE */
281+struct opregion_asle {
282+ u32 ardy; /* driver readiness */
283+ u32 aslc; /* ASLE interrupt command */
284+ u32 tche; /* technology enabled indicator */
285+ u32 alsi; /* current ALS illuminance reading */
286+ u32 bclp; /* backlight brightness to set */
287+ u32 pfit; /* panel fitting state */
288+ u32 cblv; /* current brightness level */
289+ u16 bclm[20]; /* backlight level duty cycle mapping table */
290+ u32 cpfm; /* current panel fitting mode */
291+ u32 epfm; /* enabled panel fitting modes */
292+ u8 plut[74]; /* panel LUT and identifier */
293+ u32 pfmb; /* PWM freq and min brightness */
294+ u8 rsvd[102];
295+} __attribute__((packed));
296+
297+/* ASLE irq request bits */
298+#define ASLE_SET_ALS_ILLUM (1 << 0)
299+#define ASLE_SET_BACKLIGHT (1 << 1)
300+#define ASLE_SET_PFIT (1 << 2)
301+#define ASLE_SET_PWM_FREQ (1 << 3)
302+#define ASLE_REQ_MSK 0xf
303+
304+/* response bits of ASLE irq request */
305+#define ASLE_ALS_ILLUM_FAIL (2<<10)
306+#define ASLE_BACKLIGHT_FAIL (2<<12)
307+#define ASLE_PFIT_FAIL (2<<14)
308+#define ASLE_PWM_FREQ_FAIL (2<<16)
309+
310+/* ASLE backlight brightness to set */
311+#define ASLE_BCLP_VALID (1<<31)
312+#define ASLE_BCLP_MSK (~(1<<31))
313+
314+/* ASLE panel fitting request */
315+#define ASLE_PFIT_VALID (1<<31)
316+#define ASLE_PFIT_CENTER (1<<0)
317+#define ASLE_PFIT_STRETCH_TEXT (1<<1)
318+#define ASLE_PFIT_STRETCH_GFX (1<<2)
319+
320+/* PWM frequency and minimum brightness */
321+#define ASLE_PFMB_BRIGHTNESS_MASK (0xff)
322+#define ASLE_PFMB_BRIGHTNESS_VALID (1<<8)
323+#define ASLE_PFMB_PWM_MASK (0x7ffffe00)
324+#define ASLE_PFMB_PWM_VALID (1<<31)
325+
326+#define ASLE_CBLV_VALID (1<<31)
327+
328+static u32 asle_set_backlight(struct drm_device *dev, u32 bclp)
329+{
330+ struct drm_i915_private *dev_priv = dev->dev_private;
331+ struct opregion_asle *asle = dev_priv->opregion.asle;
332+ u32 blc_pwm_ctl, blc_pwm_ctl2;
333+
334+ if (!(bclp & ASLE_BCLP_VALID))
335+ return ASLE_BACKLIGHT_FAIL;
336+
337+ bclp &= ASLE_BCLP_MSK;
338+ if (bclp < 0 || bclp > 255)
339+ return ASLE_BACKLIGHT_FAIL;
340+
341+ blc_pwm_ctl = I915_READ(BLC_PWM_CTL);
342+ blc_pwm_ctl &= ~BACKLIGHT_DUTY_CYCLE_MASK;
343+ blc_pwm_ctl2 = I915_READ(BLC_PWM_CTL2);
344+
345+ if (blc_pwm_ctl2 & BLM_COMBINATION_MODE)
346+ pci_write_config_dword(dev->pdev, PCI_LBPC, bclp);
347+ else
348+ I915_WRITE(BLC_PWM_CTL, blc_pwm_ctl | ((bclp * 0x101)-1));
349+
350+ asle->cblv = (bclp*0x64)/0xff | ASLE_CBLV_VALID;
351+
352+ return 0;
353+}
354+
355+static u32 asle_set_als_illum(struct drm_device *dev, u32 alsi)
356+{
357+ /* alsi is the current ALS reading in lux. 0 indicates below sensor
358+ range, 0xffff indicates above sensor range. 1-0xfffe are valid */
359+ return 0;
360+}
361+
362+static u32 asle_set_pwm_freq(struct drm_device *dev, u32 pfmb)
363+{
364+ struct drm_i915_private *dev_priv = dev->dev_private;
365+ if (pfmb & ASLE_PFMB_PWM_VALID) {
366+ u32 blc_pwm_ctl = I915_READ(BLC_PWM_CTL);
367+ u32 pwm = pfmb & ASLE_PFMB_PWM_MASK;
368+ blc_pwm_ctl &= BACKLIGHT_DUTY_CYCLE_MASK;
369+ pwm = pwm >> 9;
370+ /* FIXME - what do we do with the PWM? */
371+ }
372+ return 0;
373+}
374+
375+static u32 asle_set_pfit(struct drm_device *dev, u32 pfit)
376+{
377+ /* Panel fitting is currently controlled by the X code, so this is a
378+ noop until modesetting support works fully */
379+ if (!(pfit & ASLE_PFIT_VALID))
380+ return ASLE_PFIT_FAIL;
381+ return 0;
382+}
383+
384+void opregion_asle_intr(struct drm_device *dev)
385+{
386+ struct drm_i915_private *dev_priv = dev->dev_private;
387+ struct opregion_asle *asle = dev_priv->opregion.asle;
388+ u32 asle_stat = 0;
389+ u32 asle_req;
390+
391+ if (!asle)
392+ return;
393+
394+ asle_req = asle->aslc & ASLE_REQ_MSK;
395+
396+ if (!asle_req) {
397+ DRM_DEBUG("non asle set request??\n");
398+ return;
399+ }
400+
401+ if (asle_req & ASLE_SET_ALS_ILLUM)
402+ asle_stat |= asle_set_als_illum(dev, asle->alsi);
403+
404+ if (asle_req & ASLE_SET_BACKLIGHT)
405+ asle_stat |= asle_set_backlight(dev, asle->bclp);
406+
407+ if (asle_req & ASLE_SET_PFIT)
408+ asle_stat |= asle_set_pfit(dev, asle->pfit);
409+
410+ if (asle_req & ASLE_SET_PWM_FREQ)
411+ asle_stat |= asle_set_pwm_freq(dev, asle->pfmb);
412+
413+ asle->aslc = asle_stat;
414+}
415+
416+#define ASLE_ALS_EN (1<<0)
417+#define ASLE_BLC_EN (1<<1)
418+#define ASLE_PFIT_EN (1<<2)
419+#define ASLE_PFMB_EN (1<<3)
420+
421+void opregion_enable_asle(struct drm_device *dev)
422+{
423+ struct drm_i915_private *dev_priv = dev->dev_private;
424+ struct opregion_asle *asle = dev_priv->opregion.asle;
425+
426+ if (asle) {
427+ u32 pipeb_stats = I915_READ(PIPEBSTAT);
428+ if (IS_MOBILE(dev)) {
429+ /* Many devices trigger events with a write to the
430+ legacy backlight controller, so we need to ensure
431+ that it's able to generate interrupts */
432+ I915_WRITE(PIPEBSTAT, pipeb_stats |=
433+ I915_LEGACY_BLC_EVENT_ENABLE);
434+ i915_enable_irq(dev_priv, I915_ASLE_INTERRUPT |
435+ I915_DISPLAY_PIPE_B_EVENT_INTERRUPT);
436+ } else
437+ i915_enable_irq(dev_priv, I915_ASLE_INTERRUPT);
438+
439+ asle->tche = ASLE_ALS_EN | ASLE_BLC_EN | ASLE_PFIT_EN |
440+ ASLE_PFMB_EN;
441+ asle->ardy = 1;
442+ }
443+}
444+
445+#define ACPI_EV_DISPLAY_SWITCH (1<<0)
446+#define ACPI_EV_LID (1<<1)
447+#define ACPI_EV_DOCK (1<<2)
448+
449+static struct intel_opregion *system_opregion;
450+
451+int intel_opregion_video_event(struct notifier_block *nb, unsigned long val,
452+ void *data)
453+{
454+ /* The only video events relevant to opregion are 0x80. These indicate
455+ either a docking event, lid switch or display switch request. In
456+ Linux, these are handled by the dock, button and video drivers.
457+ We might want to fix the video driver to be opregion-aware in
458+ future, but right now we just indicate to the firmware that the
459+ request has been handled */
460+
461+ struct opregion_acpi *acpi;
462+
463+ if (!system_opregion)
464+ return NOTIFY_DONE;
465+
466+ acpi = system_opregion->acpi;
467+ acpi->csts = 0;
468+
469+ return NOTIFY_OK;
470+}
471+
472+static struct notifier_block intel_opregion_notifier = {
473+ .notifier_call = intel_opregion_video_event,
474+};
475+
476+int intel_opregion_init(struct drm_device *dev)
477+{
478+ struct drm_i915_private *dev_priv = dev->dev_private;
479+ struct intel_opregion *opregion = &dev_priv->opregion;
480+ void *base;
481+ u32 asls, mboxes;
482+ int err = 0;
483+
484+ pci_read_config_dword(dev->pdev, PCI_ASLS, &asls);
485+ DRM_DEBUG("graphic opregion physical addr: 0x%x\n", asls);
486+ if (asls == 0) {
487+ DRM_DEBUG("ACPI OpRegion not supported!\n");
488+ return -ENOTSUPP;
489+ }
490+
491+ base = ioremap(asls, OPREGION_SZ);
492+ if (!base)
493+ return -ENOMEM;
494+
495+ opregion->header = base;
496+ if (memcmp(opregion->header->signature, OPREGION_SIGNATURE, 16)) {
497+ DRM_DEBUG("opregion signature mismatch\n");
498+ err = -EINVAL;
499+ goto err_out;
500+ }
501+
502+ mboxes = opregion->header->mboxes;
503+ if (mboxes & MBOX_ACPI) {
504+ DRM_DEBUG("Public ACPI methods supported\n");
505+ opregion->acpi = base + OPREGION_ACPI_OFFSET;
506+ } else {
507+ DRM_DEBUG("Public ACPI methods not supported\n");
508+ err = -ENOTSUPP;
509+ goto err_out;
510+ }
511+ opregion->enabled = 1;
512+
513+ if (mboxes & MBOX_SWSCI) {
514+ DRM_DEBUG("SWSCI supported\n");
515+ opregion->swsci = base + OPREGION_SWSCI_OFFSET;
516+ }
517+ if (mboxes & MBOX_ASLE) {
518+ DRM_DEBUG("ASLE supported\n");
519+ opregion->asle = base + OPREGION_ASLE_OFFSET;
520+ }
521+
522+ /* Notify BIOS we are ready to handle ACPI video ext notifs.
523+ * Right now, all the events are handled by the ACPI video module.
524+ * We don't actually need to do anything with them. */
525+ opregion->acpi->csts = 0;
526+ opregion->acpi->drdy = 1;
527+
528+ system_opregion = opregion;
529+ register_acpi_notifier(&intel_opregion_notifier);
530+
531+ return 0;
532+
533+err_out:
534+ iounmap(opregion->header);
535+ opregion->header = NULL;
536+ return err;
537+}
538+
539+void intel_opregion_free(struct drm_device *dev)
540+{
541+ struct drm_i915_private *dev_priv = dev->dev_private;
542+ struct intel_opregion *opregion = &dev_priv->opregion;
543+
544+ if (!opregion->enabled)
545+ return;
546+
547+ opregion->acpi->drdy = 0;
548+
549+ system_opregion = NULL;
550+ unregister_acpi_notifier(&intel_opregion_notifier);
551+
552+ /* just clear all opregion memory pointers now */
553+ iounmap(opregion->header);
554+ opregion->header = NULL;
555+ opregion->acpi = NULL;
556+ opregion->swsci = NULL;
557+ opregion->asle = NULL;
558+
559+ opregion->enabled = 0;
560+}
561diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
562index 477c64e..43ad2cb 100644
563--- a/drivers/gpu/drm/i915/i915_reg.h
564+++ b/drivers/gpu/drm/i915/i915_reg.h
565@@ -740,6 +740,7 @@
566 #define BLC_PWM_CTL 0x61254
567 #define BACKLIGHT_MODULATION_FREQ_SHIFT (17)
568 #define BLC_PWM_CTL2 0x61250 /* 965+ only */
569+#define BLM_COMBINATION_MODE (1 << 30)
570 /*
571 * This is the most significant 15 bits of the number of backlight cycles in a
572 * complete cycle of the modulated backlight control.
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27/0009-drm-fix-sysfs-error-path.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27/0009-drm-fix-sysfs-error-path.patch
new file mode 100644
index 0000000000..8dea824804
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27/0009-drm-fix-sysfs-error-path.patch
@@ -0,0 +1,23 @@
1commit 2e9c9eedfe0be777c051a2198dddf459adcc407b
2Author: Dave Airlie <airlied@redhat.com>
3Date: Tue Sep 2 10:06:06 2008 +1000
4
5 drm: fix sysfs error path.
6
7 Pointed out by Roel Kluin on dri-devel.
8
9 Signed-off-by: Dave Airlie <airlied@redhat.com>
10
11diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
12index af211a0..1611b9b 100644
13--- a/drivers/gpu/drm/drm_sysfs.c
14+++ b/drivers/gpu/drm/drm_sysfs.c
15@@ -184,7 +184,7 @@ int drm_sysfs_device_add(struct drm_minor *minor)
16 err_out_files:
17 if (i > 0)
18 for (j = 0; j < i; j++)
19- device_remove_file(&minor->kdev, &device_attrs[i]);
20+ device_remove_file(&minor->kdev, &device_attrs[j]);
21 device_unregister(&minor->kdev);
22 err_out:
23
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27/0010-i915-separate-suspend-resume-functions.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27/0010-i915-separate-suspend-resume-functions.patch
new file mode 100644
index 0000000000..897d50c39b
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27/0010-i915-separate-suspend-resume-functions.patch
@@ -0,0 +1,1079 @@
1commit a850828c640735fb410c782717c9eb7f8474e356
2Author: Jesse Barnes <jbarnes@virtuousgeek.org>
3Date: Mon Aug 25 15:11:06 2008 -0700
4
5 separate i915 suspend/resume functions into their own file
6
7 [Patch against drm-next. Consider this a trial balloon for our new Linux
8 development model.]
9
10 This is a big chunk of code. Separating it out makes it easier to change
11 without churn on the main i915_drv.c file (and there will be churn as we
12 fix bugs and add things like kernel mode setting). Also makes it easier
13 to share this file with BSD.
14
15 Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
16 Signed-off-by: Dave Airlie <airlied@redhat.com>
17
18diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
19index b032808..c4bbda6 100644
20--- a/drivers/gpu/drm/i915/Makefile
21+++ b/drivers/gpu/drm/i915/Makefile
22@@ -3,7 +3,8 @@
23 # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
24
25 ccflags-y := -Iinclude/drm
26-i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o i915_opregion.o
27+i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o i915_opregion.o \
28+ i915_suspend.o
29
30 i915-$(CONFIG_COMPAT) += i915_ioc32.o
31
32diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
33index d95eca2..eff66ed 100644
34--- a/drivers/gpu/drm/i915/i915_drv.c
35+++ b/drivers/gpu/drm/i915/i915_drv.c
36@@ -38,211 +38,9 @@ static struct pci_device_id pciidlist[] = {
37 i915_PCI_IDS
38 };
39
40-enum pipe {
41- PIPE_A = 0,
42- PIPE_B,
43-};
44-
45-static bool i915_pipe_enabled(struct drm_device *dev, enum pipe pipe)
46-{
47- struct drm_i915_private *dev_priv = dev->dev_private;
48-
49- if (pipe == PIPE_A)
50- return (I915_READ(DPLL_A) & DPLL_VCO_ENABLE);
51- else
52- return (I915_READ(DPLL_B) & DPLL_VCO_ENABLE);
53-}
54-
55-static void i915_save_palette(struct drm_device *dev, enum pipe pipe)
56-{
57- struct drm_i915_private *dev_priv = dev->dev_private;
58- unsigned long reg = (pipe == PIPE_A ? PALETTE_A : PALETTE_B);
59- u32 *array;
60- int i;
61-
62- if (!i915_pipe_enabled(dev, pipe))
63- return;
64-
65- if (pipe == PIPE_A)
66- array = dev_priv->save_palette_a;
67- else
68- array = dev_priv->save_palette_b;
69-
70- for(i = 0; i < 256; i++)
71- array[i] = I915_READ(reg + (i << 2));
72-}
73-
74-static void i915_restore_palette(struct drm_device *dev, enum pipe pipe)
75-{
76- struct drm_i915_private *dev_priv = dev->dev_private;
77- unsigned long reg = (pipe == PIPE_A ? PALETTE_A : PALETTE_B);
78- u32 *array;
79- int i;
80-
81- if (!i915_pipe_enabled(dev, pipe))
82- return;
83-
84- if (pipe == PIPE_A)
85- array = dev_priv->save_palette_a;
86- else
87- array = dev_priv->save_palette_b;
88-
89- for(i = 0; i < 256; i++)
90- I915_WRITE(reg + (i << 2), array[i]);
91-}
92-
93-static u8 i915_read_indexed(u16 index_port, u16 data_port, u8 reg)
94-{
95- outb(reg, index_port);
96- return inb(data_port);
97-}
98-
99-static u8 i915_read_ar(u16 st01, u8 reg, u16 palette_enable)
100-{
101- inb(st01);
102- outb(palette_enable | reg, VGA_AR_INDEX);
103- return inb(VGA_AR_DATA_READ);
104-}
105-
106-static void i915_write_ar(u8 st01, u8 reg, u8 val, u16 palette_enable)
107-{
108- inb(st01);
109- outb(palette_enable | reg, VGA_AR_INDEX);
110- outb(val, VGA_AR_DATA_WRITE);
111-}
112-
113-static void i915_write_indexed(u16 index_port, u16 data_port, u8 reg, u8 val)
114-{
115- outb(reg, index_port);
116- outb(val, data_port);
117-}
118-
119-static void i915_save_vga(struct drm_device *dev)
120-{
121- struct drm_i915_private *dev_priv = dev->dev_private;
122- int i;
123- u16 cr_index, cr_data, st01;
124-
125- /* VGA color palette registers */
126- dev_priv->saveDACMASK = inb(VGA_DACMASK);
127- /* DACCRX automatically increments during read */
128- outb(0, VGA_DACRX);
129- /* Read 3 bytes of color data from each index */
130- for (i = 0; i < 256 * 3; i++)
131- dev_priv->saveDACDATA[i] = inb(VGA_DACDATA);
132-
133- /* MSR bits */
134- dev_priv->saveMSR = inb(VGA_MSR_READ);
135- if (dev_priv->saveMSR & VGA_MSR_CGA_MODE) {
136- cr_index = VGA_CR_INDEX_CGA;
137- cr_data = VGA_CR_DATA_CGA;
138- st01 = VGA_ST01_CGA;
139- } else {
140- cr_index = VGA_CR_INDEX_MDA;
141- cr_data = VGA_CR_DATA_MDA;
142- st01 = VGA_ST01_MDA;
143- }
144-
145- /* CRT controller regs */
146- i915_write_indexed(cr_index, cr_data, 0x11,
147- i915_read_indexed(cr_index, cr_data, 0x11) &
148- (~0x80));
149- for (i = 0; i <= 0x24; i++)
150- dev_priv->saveCR[i] =
151- i915_read_indexed(cr_index, cr_data, i);
152- /* Make sure we don't turn off CR group 0 writes */
153- dev_priv->saveCR[0x11] &= ~0x80;
154-
155- /* Attribute controller registers */
156- inb(st01);
157- dev_priv->saveAR_INDEX = inb(VGA_AR_INDEX);
158- for (i = 0; i <= 0x14; i++)
159- dev_priv->saveAR[i] = i915_read_ar(st01, i, 0);
160- inb(st01);
161- outb(dev_priv->saveAR_INDEX, VGA_AR_INDEX);
162- inb(st01);
163-
164- /* Graphics controller registers */
165- for (i = 0; i < 9; i++)
166- dev_priv->saveGR[i] =
167- i915_read_indexed(VGA_GR_INDEX, VGA_GR_DATA, i);
168-
169- dev_priv->saveGR[0x10] =
170- i915_read_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x10);
171- dev_priv->saveGR[0x11] =
172- i915_read_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x11);
173- dev_priv->saveGR[0x18] =
174- i915_read_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x18);
175-
176- /* Sequencer registers */
177- for (i = 0; i < 8; i++)
178- dev_priv->saveSR[i] =
179- i915_read_indexed(VGA_SR_INDEX, VGA_SR_DATA, i);
180-}
181-
182-static void i915_restore_vga(struct drm_device *dev)
183-{
184- struct drm_i915_private *dev_priv = dev->dev_private;
185- int i;
186- u16 cr_index, cr_data, st01;
187-
188- /* MSR bits */
189- outb(dev_priv->saveMSR, VGA_MSR_WRITE);
190- if (dev_priv->saveMSR & VGA_MSR_CGA_MODE) {
191- cr_index = VGA_CR_INDEX_CGA;
192- cr_data = VGA_CR_DATA_CGA;
193- st01 = VGA_ST01_CGA;
194- } else {
195- cr_index = VGA_CR_INDEX_MDA;
196- cr_data = VGA_CR_DATA_MDA;
197- st01 = VGA_ST01_MDA;
198- }
199-
200- /* Sequencer registers, don't write SR07 */
201- for (i = 0; i < 7; i++)
202- i915_write_indexed(VGA_SR_INDEX, VGA_SR_DATA, i,
203- dev_priv->saveSR[i]);
204-
205- /* CRT controller regs */
206- /* Enable CR group 0 writes */
207- i915_write_indexed(cr_index, cr_data, 0x11, dev_priv->saveCR[0x11]);
208- for (i = 0; i <= 0x24; i++)
209- i915_write_indexed(cr_index, cr_data, i, dev_priv->saveCR[i]);
210-
211- /* Graphics controller regs */
212- for (i = 0; i < 9; i++)
213- i915_write_indexed(VGA_GR_INDEX, VGA_GR_DATA, i,
214- dev_priv->saveGR[i]);
215-
216- i915_write_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x10,
217- dev_priv->saveGR[0x10]);
218- i915_write_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x11,
219- dev_priv->saveGR[0x11]);
220- i915_write_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x18,
221- dev_priv->saveGR[0x18]);
222-
223- /* Attribute controller registers */
224- inb(st01);
225- for (i = 0; i <= 0x14; i++)
226- i915_write_ar(st01, i, dev_priv->saveAR[i], 0);
227- inb(st01); /* switch back to index mode */
228- outb(dev_priv->saveAR_INDEX | 0x20, VGA_AR_INDEX);
229- inb(st01);
230-
231- /* VGA color palette registers */
232- outb(dev_priv->saveDACMASK, VGA_DACMASK);
233- /* DACCRX automatically increments during read */
234- outb(0, VGA_DACWX);
235- /* Read 3 bytes of color data from each index */
236- for (i = 0; i < 256 * 3; i++)
237- outb(dev_priv->saveDACDATA[i], VGA_DACDATA);
238-
239-}
240-
241 static int i915_suspend(struct drm_device *dev, pm_message_t state)
242 {
243 struct drm_i915_private *dev_priv = dev->dev_private;
244- int i;
245
246 if (!dev || !dev_priv) {
247 printk(KERN_ERR "dev: %p, dev_priv: %p\n", dev, dev_priv);
248@@ -254,122 +52,8 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state)
249 return 0;
250
251 pci_save_state(dev->pdev);
252- pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB);
253-
254- /* Display arbitration control */
255- dev_priv->saveDSPARB = I915_READ(DSPARB);
256-
257- /* Pipe & plane A info */
258- dev_priv->savePIPEACONF = I915_READ(PIPEACONF);
259- dev_priv->savePIPEASRC = I915_READ(PIPEASRC);
260- dev_priv->saveFPA0 = I915_READ(FPA0);
261- dev_priv->saveFPA1 = I915_READ(FPA1);
262- dev_priv->saveDPLL_A = I915_READ(DPLL_A);
263- if (IS_I965G(dev))
264- dev_priv->saveDPLL_A_MD = I915_READ(DPLL_A_MD);
265- dev_priv->saveHTOTAL_A = I915_READ(HTOTAL_A);
266- dev_priv->saveHBLANK_A = I915_READ(HBLANK_A);
267- dev_priv->saveHSYNC_A = I915_READ(HSYNC_A);
268- dev_priv->saveVTOTAL_A = I915_READ(VTOTAL_A);
269- dev_priv->saveVBLANK_A = I915_READ(VBLANK_A);
270- dev_priv->saveVSYNC_A = I915_READ(VSYNC_A);
271- dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A);
272-
273- dev_priv->saveDSPACNTR = I915_READ(DSPACNTR);
274- dev_priv->saveDSPASTRIDE = I915_READ(DSPASTRIDE);
275- dev_priv->saveDSPASIZE = I915_READ(DSPASIZE);
276- dev_priv->saveDSPAPOS = I915_READ(DSPAPOS);
277- dev_priv->saveDSPAADDR = I915_READ(DSPAADDR);
278- if (IS_I965G(dev)) {
279- dev_priv->saveDSPASURF = I915_READ(DSPASURF);
280- dev_priv->saveDSPATILEOFF = I915_READ(DSPATILEOFF);
281- }
282- i915_save_palette(dev, PIPE_A);
283- dev_priv->savePIPEASTAT = I915_READ(PIPEASTAT);
284-
285- /* Pipe & plane B info */
286- dev_priv->savePIPEBCONF = I915_READ(PIPEBCONF);
287- dev_priv->savePIPEBSRC = I915_READ(PIPEBSRC);
288- dev_priv->saveFPB0 = I915_READ(FPB0);
289- dev_priv->saveFPB1 = I915_READ(FPB1);
290- dev_priv->saveDPLL_B = I915_READ(DPLL_B);
291- if (IS_I965G(dev))
292- dev_priv->saveDPLL_B_MD = I915_READ(DPLL_B_MD);
293- dev_priv->saveHTOTAL_B = I915_READ(HTOTAL_B);
294- dev_priv->saveHBLANK_B = I915_READ(HBLANK_B);
295- dev_priv->saveHSYNC_B = I915_READ(HSYNC_B);
296- dev_priv->saveVTOTAL_B = I915_READ(VTOTAL_B);
297- dev_priv->saveVBLANK_B = I915_READ(VBLANK_B);
298- dev_priv->saveVSYNC_B = I915_READ(VSYNC_B);
299- dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A);
300-
301- dev_priv->saveDSPBCNTR = I915_READ(DSPBCNTR);
302- dev_priv->saveDSPBSTRIDE = I915_READ(DSPBSTRIDE);
303- dev_priv->saveDSPBSIZE = I915_READ(DSPBSIZE);
304- dev_priv->saveDSPBPOS = I915_READ(DSPBPOS);
305- dev_priv->saveDSPBADDR = I915_READ(DSPBADDR);
306- if (IS_I965GM(dev) || IS_IGD_GM(dev)) {
307- dev_priv->saveDSPBSURF = I915_READ(DSPBSURF);
308- dev_priv->saveDSPBTILEOFF = I915_READ(DSPBTILEOFF);
309- }
310- i915_save_palette(dev, PIPE_B);
311- dev_priv->savePIPEBSTAT = I915_READ(PIPEBSTAT);
312-
313- /* CRT state */
314- dev_priv->saveADPA = I915_READ(ADPA);
315
316- /* LVDS state */
317- dev_priv->savePP_CONTROL = I915_READ(PP_CONTROL);
318- dev_priv->savePFIT_PGM_RATIOS = I915_READ(PFIT_PGM_RATIOS);
319- dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_CTL);
320- if (IS_I965G(dev))
321- dev_priv->saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_CTL2);
322- if (IS_MOBILE(dev) && !IS_I830(dev))
323- dev_priv->saveLVDS = I915_READ(LVDS);
324- if (!IS_I830(dev) && !IS_845G(dev))
325- dev_priv->savePFIT_CONTROL = I915_READ(PFIT_CONTROL);
326- dev_priv->savePP_ON_DELAYS = I915_READ(PP_ON_DELAYS);
327- dev_priv->savePP_OFF_DELAYS = I915_READ(PP_OFF_DELAYS);
328- dev_priv->savePP_DIVISOR = I915_READ(PP_DIVISOR);
329-
330- /* FIXME: save TV & SDVO state */
331-
332- /* FBC state */
333- dev_priv->saveFBC_CFB_BASE = I915_READ(FBC_CFB_BASE);
334- dev_priv->saveFBC_LL_BASE = I915_READ(FBC_LL_BASE);
335- dev_priv->saveFBC_CONTROL2 = I915_READ(FBC_CONTROL2);
336- dev_priv->saveFBC_CONTROL = I915_READ(FBC_CONTROL);
337-
338- /* Interrupt state */
339- dev_priv->saveIIR = I915_READ(IIR);
340- dev_priv->saveIER = I915_READ(IER);
341- dev_priv->saveIMR = I915_READ(IMR);
342-
343- /* VGA state */
344- dev_priv->saveVGA0 = I915_READ(VGA0);
345- dev_priv->saveVGA1 = I915_READ(VGA1);
346- dev_priv->saveVGA_PD = I915_READ(VGA_PD);
347- dev_priv->saveVGACNTRL = I915_READ(VGACNTRL);
348-
349- /* Clock gating state */
350- dev_priv->saveD_STATE = I915_READ(D_STATE);
351- dev_priv->saveCG_2D_DIS = I915_READ(CG_2D_DIS);
352-
353- /* Cache mode state */
354- dev_priv->saveCACHE_MODE_0 = I915_READ(CACHE_MODE_0);
355-
356- /* Memory Arbitration state */
357- dev_priv->saveMI_ARB_STATE = I915_READ(MI_ARB_STATE);
358-
359- /* Scratch space */
360- for (i = 0; i < 16; i++) {
361- dev_priv->saveSWF0[i] = I915_READ(SWF00 + (i << 2));
362- dev_priv->saveSWF1[i] = I915_READ(SWF10 + (i << 2));
363- }
364- for (i = 0; i < 3; i++)
365- dev_priv->saveSWF2[i] = I915_READ(SWF30 + (i << 2));
366-
367- i915_save_vga(dev);
368+ i915_save_state(dev);
369
370 intel_opregion_free(dev);
371
372@@ -384,155 +68,13 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state)
373
374 static int i915_resume(struct drm_device *dev)
375 {
376- struct drm_i915_private *dev_priv = dev->dev_private;
377- int i;
378-
379 pci_set_power_state(dev->pdev, PCI_D0);
380 pci_restore_state(dev->pdev);
381 if (pci_enable_device(dev->pdev))
382 return -1;
383 pci_set_master(dev->pdev);
384
385- pci_write_config_byte(dev->pdev, LBB, dev_priv->saveLBB);
386-
387- I915_WRITE(DSPARB, dev_priv->saveDSPARB);
388-
389- /* Pipe & plane A info */
390- /* Prime the clock */
391- if (dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) {
392- I915_WRITE(DPLL_A, dev_priv->saveDPLL_A &
393- ~DPLL_VCO_ENABLE);
394- udelay(150);
395- }
396- I915_WRITE(FPA0, dev_priv->saveFPA0);
397- I915_WRITE(FPA1, dev_priv->saveFPA1);
398- /* Actually enable it */
399- I915_WRITE(DPLL_A, dev_priv->saveDPLL_A);
400- udelay(150);
401- if (IS_I965G(dev))
402- I915_WRITE(DPLL_A_MD, dev_priv->saveDPLL_A_MD);
403- udelay(150);
404-
405- /* Restore mode */
406- I915_WRITE(HTOTAL_A, dev_priv->saveHTOTAL_A);
407- I915_WRITE(HBLANK_A, dev_priv->saveHBLANK_A);
408- I915_WRITE(HSYNC_A, dev_priv->saveHSYNC_A);
409- I915_WRITE(VTOTAL_A, dev_priv->saveVTOTAL_A);
410- I915_WRITE(VBLANK_A, dev_priv->saveVBLANK_A);
411- I915_WRITE(VSYNC_A, dev_priv->saveVSYNC_A);
412- I915_WRITE(BCLRPAT_A, dev_priv->saveBCLRPAT_A);
413-
414- /* Restore plane info */
415- I915_WRITE(DSPASIZE, dev_priv->saveDSPASIZE);
416- I915_WRITE(DSPAPOS, dev_priv->saveDSPAPOS);
417- I915_WRITE(PIPEASRC, dev_priv->savePIPEASRC);
418- I915_WRITE(DSPAADDR, dev_priv->saveDSPAADDR);
419- I915_WRITE(DSPASTRIDE, dev_priv->saveDSPASTRIDE);
420- if (IS_I965G(dev)) {
421- I915_WRITE(DSPASURF, dev_priv->saveDSPASURF);
422- I915_WRITE(DSPATILEOFF, dev_priv->saveDSPATILEOFF);
423- }
424-
425- I915_WRITE(PIPEACONF, dev_priv->savePIPEACONF);
426-
427- i915_restore_palette(dev, PIPE_A);
428- /* Enable the plane */
429- I915_WRITE(DSPACNTR, dev_priv->saveDSPACNTR);
430- I915_WRITE(DSPAADDR, I915_READ(DSPAADDR));
431-
432- /* Pipe & plane B info */
433- if (dev_priv->saveDPLL_B & DPLL_VCO_ENABLE) {
434- I915_WRITE(DPLL_B, dev_priv->saveDPLL_B &
435- ~DPLL_VCO_ENABLE);
436- udelay(150);
437- }
438- I915_WRITE(FPB0, dev_priv->saveFPB0);
439- I915_WRITE(FPB1, dev_priv->saveFPB1);
440- /* Actually enable it */
441- I915_WRITE(DPLL_B, dev_priv->saveDPLL_B);
442- udelay(150);
443- if (IS_I965G(dev))
444- I915_WRITE(DPLL_B_MD, dev_priv->saveDPLL_B_MD);
445- udelay(150);
446-
447- /* Restore mode */
448- I915_WRITE(HTOTAL_B, dev_priv->saveHTOTAL_B);
449- I915_WRITE(HBLANK_B, dev_priv->saveHBLANK_B);
450- I915_WRITE(HSYNC_B, dev_priv->saveHSYNC_B);
451- I915_WRITE(VTOTAL_B, dev_priv->saveVTOTAL_B);
452- I915_WRITE(VBLANK_B, dev_priv->saveVBLANK_B);
453- I915_WRITE(VSYNC_B, dev_priv->saveVSYNC_B);
454- I915_WRITE(BCLRPAT_B, dev_priv->saveBCLRPAT_B);
455-
456- /* Restore plane info */
457- I915_WRITE(DSPBSIZE, dev_priv->saveDSPBSIZE);
458- I915_WRITE(DSPBPOS, dev_priv->saveDSPBPOS);
459- I915_WRITE(PIPEBSRC, dev_priv->savePIPEBSRC);
460- I915_WRITE(DSPBADDR, dev_priv->saveDSPBADDR);
461- I915_WRITE(DSPBSTRIDE, dev_priv->saveDSPBSTRIDE);
462- if (IS_I965G(dev)) {
463- I915_WRITE(DSPBSURF, dev_priv->saveDSPBSURF);
464- I915_WRITE(DSPBTILEOFF, dev_priv->saveDSPBTILEOFF);
465- }
466-
467- I915_WRITE(PIPEBCONF, dev_priv->savePIPEBCONF);
468-
469- i915_restore_palette(dev, PIPE_B);
470- /* Enable the plane */
471- I915_WRITE(DSPBCNTR, dev_priv->saveDSPBCNTR);
472- I915_WRITE(DSPBADDR, I915_READ(DSPBADDR));
473-
474- /* CRT state */
475- I915_WRITE(ADPA, dev_priv->saveADPA);
476-
477- /* LVDS state */
478- if (IS_I965G(dev))
479- I915_WRITE(BLC_PWM_CTL2, dev_priv->saveBLC_PWM_CTL2);
480- if (IS_MOBILE(dev) && !IS_I830(dev))
481- I915_WRITE(LVDS, dev_priv->saveLVDS);
482- if (!IS_I830(dev) && !IS_845G(dev))
483- I915_WRITE(PFIT_CONTROL, dev_priv->savePFIT_CONTROL);
484-
485- I915_WRITE(PFIT_PGM_RATIOS, dev_priv->savePFIT_PGM_RATIOS);
486- I915_WRITE(BLC_PWM_CTL, dev_priv->saveBLC_PWM_CTL);
487- I915_WRITE(PP_ON_DELAYS, dev_priv->savePP_ON_DELAYS);
488- I915_WRITE(PP_OFF_DELAYS, dev_priv->savePP_OFF_DELAYS);
489- I915_WRITE(PP_DIVISOR, dev_priv->savePP_DIVISOR);
490- I915_WRITE(PP_CONTROL, dev_priv->savePP_CONTROL);
491-
492- /* FIXME: restore TV & SDVO state */
493-
494- /* FBC info */
495- I915_WRITE(FBC_CFB_BASE, dev_priv->saveFBC_CFB_BASE);
496- I915_WRITE(FBC_LL_BASE, dev_priv->saveFBC_LL_BASE);
497- I915_WRITE(FBC_CONTROL2, dev_priv->saveFBC_CONTROL2);
498- I915_WRITE(FBC_CONTROL, dev_priv->saveFBC_CONTROL);
499-
500- /* VGA state */
501- I915_WRITE(VGACNTRL, dev_priv->saveVGACNTRL);
502- I915_WRITE(VGA0, dev_priv->saveVGA0);
503- I915_WRITE(VGA1, dev_priv->saveVGA1);
504- I915_WRITE(VGA_PD, dev_priv->saveVGA_PD);
505- udelay(150);
506-
507- /* Clock gating state */
508- I915_WRITE (D_STATE, dev_priv->saveD_STATE);
509- I915_WRITE(CG_2D_DIS, dev_priv->saveCG_2D_DIS);
510-
511- /* Cache mode state */
512- I915_WRITE (CACHE_MODE_0, dev_priv->saveCACHE_MODE_0 | 0xffff0000);
513-
514- /* Memory arbitration state */
515- I915_WRITE (MI_ARB_STATE, dev_priv->saveMI_ARB_STATE | 0xffff0000);
516-
517- for (i = 0; i < 16; i++) {
518- I915_WRITE(SWF00 + (i << 2), dev_priv->saveSWF0[i]);
519- I915_WRITE(SWF10 + (i << 2), dev_priv->saveSWF1[i+7]);
520- }
521- for (i = 0; i < 3; i++)
522- I915_WRITE(SWF30 + (i << 2), dev_priv->saveSWF2[i]);
523-
524- i915_restore_vga(dev);
525+ i915_restore_state(dev);
526
527 intel_opregion_init(dev);
528
529diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
530index e4bd01c..a82b487 100644
531--- a/drivers/gpu/drm/i915/i915_drv.h
532+++ b/drivers/gpu/drm/i915/i915_drv.h
533@@ -41,6 +41,11 @@
534 #define DRIVER_DESC "Intel Graphics"
535 #define DRIVER_DATE "20060119"
536
537+enum pipe {
538+ PIPE_A = 0,
539+ PIPE_B,
540+};
541+
542 /* Interface history:
543 *
544 * 1.1: Original.
545@@ -269,6 +274,10 @@ extern void i915_mem_takedown(struct mem_block **heap);
546 extern void i915_mem_release(struct drm_device * dev,
547 struct drm_file *file_priv, struct mem_block *heap);
548
549+/* i915_suspend.c */
550+extern int i915_save_state(struct drm_device *dev);
551+extern int i915_restore_state(struct drm_device *dev);
552+
553 /* i915_opregion.c */
554 extern int intel_opregion_init(struct drm_device *dev);
555 extern void intel_opregion_free(struct drm_device *dev);
556@@ -279,6 +288,8 @@ extern void opregion_enable_asle(struct drm_device *dev);
557 #define I915_WRITE(reg,val) DRM_WRITE32(dev_priv->mmio_map, (reg), (val))
558 #define I915_READ16(reg) DRM_READ16(dev_priv->mmio_map, (reg))
559 #define I915_WRITE16(reg,val) DRM_WRITE16(dev_priv->mmio_map, (reg), (val))
560+#define I915_READ8(reg) DRM_READ8(dev_priv->mmio_map, (reg))
561+#define I915_WRITE8(reg,val) DRM_WRITE8(dev_priv->mmio_map, (reg), (val))
562
563 #define I915_VERBOSE 0
564
565diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c
566new file mode 100644
567index 0000000..e0c1fe4
568--- /dev/null
569+++ b/drivers/gpu/drm/i915/i915_suspend.c
570@@ -0,0 +1,509 @@
571+/*
572+ *
573+ * Copyright 2008 (c) Intel Corporation
574+ * Jesse Barnes <jbarnes@virtuousgeek.org>
575+ *
576+ * Permission is hereby granted, free of charge, to any person obtaining a
577+ * copy of this software and associated documentation files (the
578+ * "Software"), to deal in the Software without restriction, including
579+ * without limitation the rights to use, copy, modify, merge, publish,
580+ * distribute, sub license, and/or sell copies of the Software, and to
581+ * permit persons to whom the Software is furnished to do so, subject to
582+ * the following conditions:
583+ *
584+ * The above copyright notice and this permission notice (including the
585+ * next paragraph) shall be included in all copies or substantial portions
586+ * of the Software.
587+ *
588+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
589+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
590+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
591+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
592+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
593+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
594+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
595+ */
596+
597+#include "drmP.h"
598+#include "drm.h"
599+#include "i915_drm.h"
600+#include "i915_drv.h"
601+
602+static bool i915_pipe_enabled(struct drm_device *dev, enum pipe pipe)
603+{
604+ struct drm_i915_private *dev_priv = dev->dev_private;
605+
606+ if (pipe == PIPE_A)
607+ return (I915_READ(DPLL_A) & DPLL_VCO_ENABLE);
608+ else
609+ return (I915_READ(DPLL_B) & DPLL_VCO_ENABLE);
610+}
611+
612+static void i915_save_palette(struct drm_device *dev, enum pipe pipe)
613+{
614+ struct drm_i915_private *dev_priv = dev->dev_private;
615+ unsigned long reg = (pipe == PIPE_A ? PALETTE_A : PALETTE_B);
616+ u32 *array;
617+ int i;
618+
619+ if (!i915_pipe_enabled(dev, pipe))
620+ return;
621+
622+ if (pipe == PIPE_A)
623+ array = dev_priv->save_palette_a;
624+ else
625+ array = dev_priv->save_palette_b;
626+
627+ for(i = 0; i < 256; i++)
628+ array[i] = I915_READ(reg + (i << 2));
629+}
630+
631+static void i915_restore_palette(struct drm_device *dev, enum pipe pipe)
632+{
633+ struct drm_i915_private *dev_priv = dev->dev_private;
634+ unsigned long reg = (pipe == PIPE_A ? PALETTE_A : PALETTE_B);
635+ u32 *array;
636+ int i;
637+
638+ if (!i915_pipe_enabled(dev, pipe))
639+ return;
640+
641+ if (pipe == PIPE_A)
642+ array = dev_priv->save_palette_a;
643+ else
644+ array = dev_priv->save_palette_b;
645+
646+ for(i = 0; i < 256; i++)
647+ I915_WRITE(reg + (i << 2), array[i]);
648+}
649+
650+static u8 i915_read_indexed(struct drm_device *dev, u16 index_port, u16 data_port, u8 reg)
651+{
652+ struct drm_i915_private *dev_priv = dev->dev_private;
653+
654+ I915_WRITE8(index_port, reg);
655+ return I915_READ8(data_port);
656+}
657+
658+static u8 i915_read_ar(struct drm_device *dev, u16 st01, u8 reg, u16 palette_enable)
659+{
660+ struct drm_i915_private *dev_priv = dev->dev_private;
661+
662+ I915_READ8(st01);
663+ I915_WRITE8(VGA_AR_INDEX, palette_enable | reg);
664+ return I915_READ8(VGA_AR_DATA_READ);
665+}
666+
667+static void i915_write_ar(struct drm_device *dev, u16 st01, u8 reg, u8 val, u16 palette_enable)
668+{
669+ struct drm_i915_private *dev_priv = dev->dev_private;
670+
671+ I915_READ8(st01);
672+ I915_WRITE8(VGA_AR_INDEX, palette_enable | reg);
673+ I915_WRITE8(VGA_AR_DATA_WRITE, val);
674+}
675+
676+static void i915_write_indexed(struct drm_device *dev, u16 index_port, u16 data_port, u8 reg, u8 val)
677+{
678+ struct drm_i915_private *dev_priv = dev->dev_private;
679+
680+ I915_WRITE8(index_port, reg);
681+ I915_WRITE8(data_port, val);
682+}
683+
684+static void i915_save_vga(struct drm_device *dev)
685+{
686+ struct drm_i915_private *dev_priv = dev->dev_private;
687+ int i;
688+ u16 cr_index, cr_data, st01;
689+
690+ /* VGA color palette registers */
691+ dev_priv->saveDACMASK = I915_READ8(VGA_DACMASK);
692+ /* DACCRX automatically increments during read */
693+ I915_WRITE8(VGA_DACRX, 0);
694+ /* Read 3 bytes of color data from each index */
695+ for (i = 0; i < 256 * 3; i++)
696+ dev_priv->saveDACDATA[i] = I915_READ8(VGA_DACDATA);
697+
698+ /* MSR bits */
699+ dev_priv->saveMSR = I915_READ8(VGA_MSR_READ);
700+ if (dev_priv->saveMSR & VGA_MSR_CGA_MODE) {
701+ cr_index = VGA_CR_INDEX_CGA;
702+ cr_data = VGA_CR_DATA_CGA;
703+ st01 = VGA_ST01_CGA;
704+ } else {
705+ cr_index = VGA_CR_INDEX_MDA;
706+ cr_data = VGA_CR_DATA_MDA;
707+ st01 = VGA_ST01_MDA;
708+ }
709+
710+ /* CRT controller regs */
711+ i915_write_indexed(dev, cr_index, cr_data, 0x11,
712+ i915_read_indexed(dev, cr_index, cr_data, 0x11) &
713+ (~0x80));
714+ for (i = 0; i <= 0x24; i++)
715+ dev_priv->saveCR[i] =
716+ i915_read_indexed(dev, cr_index, cr_data, i);
717+ /* Make sure we don't turn off CR group 0 writes */
718+ dev_priv->saveCR[0x11] &= ~0x80;
719+
720+ /* Attribute controller registers */
721+ I915_READ8(st01);
722+ dev_priv->saveAR_INDEX = I915_READ8(VGA_AR_INDEX);
723+ for (i = 0; i <= 0x14; i++)
724+ dev_priv->saveAR[i] = i915_read_ar(dev, st01, i, 0);
725+ I915_READ8(st01);
726+ I915_WRITE8(VGA_AR_INDEX, dev_priv->saveAR_INDEX);
727+ I915_READ8(st01);
728+
729+ /* Graphics controller registers */
730+ for (i = 0; i < 9; i++)
731+ dev_priv->saveGR[i] =
732+ i915_read_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, i);
733+
734+ dev_priv->saveGR[0x10] =
735+ i915_read_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x10);
736+ dev_priv->saveGR[0x11] =
737+ i915_read_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x11);
738+ dev_priv->saveGR[0x18] =
739+ i915_read_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x18);
740+
741+ /* Sequencer registers */
742+ for (i = 0; i < 8; i++)
743+ dev_priv->saveSR[i] =
744+ i915_read_indexed(dev, VGA_SR_INDEX, VGA_SR_DATA, i);
745+}
746+
747+static void i915_restore_vga(struct drm_device *dev)
748+{
749+ struct drm_i915_private *dev_priv = dev->dev_private;
750+ int i;
751+ u16 cr_index, cr_data, st01;
752+
753+ /* MSR bits */
754+ I915_WRITE8(VGA_MSR_WRITE, dev_priv->saveMSR);
755+ if (dev_priv->saveMSR & VGA_MSR_CGA_MODE) {
756+ cr_index = VGA_CR_INDEX_CGA;
757+ cr_data = VGA_CR_DATA_CGA;
758+ st01 = VGA_ST01_CGA;
759+ } else {
760+ cr_index = VGA_CR_INDEX_MDA;
761+ cr_data = VGA_CR_DATA_MDA;
762+ st01 = VGA_ST01_MDA;
763+ }
764+
765+ /* Sequencer registers, don't write SR07 */
766+ for (i = 0; i < 7; i++)
767+ i915_write_indexed(dev, VGA_SR_INDEX, VGA_SR_DATA, i,
768+ dev_priv->saveSR[i]);
769+
770+ /* CRT controller regs */
771+ /* Enable CR group 0 writes */
772+ i915_write_indexed(dev, cr_index, cr_data, 0x11, dev_priv->saveCR[0x11]);
773+ for (i = 0; i <= 0x24; i++)
774+ i915_write_indexed(dev, cr_index, cr_data, i, dev_priv->saveCR[i]);
775+
776+ /* Graphics controller regs */
777+ for (i = 0; i < 9; i++)
778+ i915_write_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, i,
779+ dev_priv->saveGR[i]);
780+
781+ i915_write_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x10,
782+ dev_priv->saveGR[0x10]);
783+ i915_write_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x11,
784+ dev_priv->saveGR[0x11]);
785+ i915_write_indexed(dev, VGA_GR_INDEX, VGA_GR_DATA, 0x18,
786+ dev_priv->saveGR[0x18]);
787+
788+ /* Attribute controller registers */
789+ I915_READ8(st01); /* switch back to index mode */
790+ for (i = 0; i <= 0x14; i++)
791+ i915_write_ar(dev, st01, i, dev_priv->saveAR[i], 0);
792+ I915_READ8(st01); /* switch back to index mode */
793+ I915_WRITE8(VGA_AR_INDEX, dev_priv->saveAR_INDEX | 0x20);
794+ I915_READ8(st01);
795+
796+ /* VGA color palette registers */
797+ I915_WRITE8(VGA_DACMASK, dev_priv->saveDACMASK);
798+ /* DACCRX automatically increments during read */
799+ I915_WRITE8(VGA_DACWX, 0);
800+ /* Read 3 bytes of color data from each index */
801+ for (i = 0; i < 256 * 3; i++)
802+ I915_WRITE8(VGA_DACDATA, dev_priv->saveDACDATA[i]);
803+
804+}
805+
806+int i915_save_state(struct drm_device *dev)
807+{
808+ struct drm_i915_private *dev_priv = dev->dev_private;
809+ int i;
810+
811+ pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB);
812+
813+ /* Display arbitration control */
814+ dev_priv->saveDSPARB = I915_READ(DSPARB);
815+
816+ /* Pipe & plane A info */
817+ dev_priv->savePIPEACONF = I915_READ(PIPEACONF);
818+ dev_priv->savePIPEASRC = I915_READ(PIPEASRC);
819+ dev_priv->saveFPA0 = I915_READ(FPA0);
820+ dev_priv->saveFPA1 = I915_READ(FPA1);
821+ dev_priv->saveDPLL_A = I915_READ(DPLL_A);
822+ if (IS_I965G(dev))
823+ dev_priv->saveDPLL_A_MD = I915_READ(DPLL_A_MD);
824+ dev_priv->saveHTOTAL_A = I915_READ(HTOTAL_A);
825+ dev_priv->saveHBLANK_A = I915_READ(HBLANK_A);
826+ dev_priv->saveHSYNC_A = I915_READ(HSYNC_A);
827+ dev_priv->saveVTOTAL_A = I915_READ(VTOTAL_A);
828+ dev_priv->saveVBLANK_A = I915_READ(VBLANK_A);
829+ dev_priv->saveVSYNC_A = I915_READ(VSYNC_A);
830+ dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A);
831+
832+ dev_priv->saveDSPACNTR = I915_READ(DSPACNTR);
833+ dev_priv->saveDSPASTRIDE = I915_READ(DSPASTRIDE);
834+ dev_priv->saveDSPASIZE = I915_READ(DSPASIZE);
835+ dev_priv->saveDSPAPOS = I915_READ(DSPAPOS);
836+ dev_priv->saveDSPAADDR = I915_READ(DSPAADDR);
837+ if (IS_I965G(dev)) {
838+ dev_priv->saveDSPASURF = I915_READ(DSPASURF);
839+ dev_priv->saveDSPATILEOFF = I915_READ(DSPATILEOFF);
840+ }
841+ i915_save_palette(dev, PIPE_A);
842+ dev_priv->savePIPEASTAT = I915_READ(PIPEASTAT);
843+
844+ /* Pipe & plane B info */
845+ dev_priv->savePIPEBCONF = I915_READ(PIPEBCONF);
846+ dev_priv->savePIPEBSRC = I915_READ(PIPEBSRC);
847+ dev_priv->saveFPB0 = I915_READ(FPB0);
848+ dev_priv->saveFPB1 = I915_READ(FPB1);
849+ dev_priv->saveDPLL_B = I915_READ(DPLL_B);
850+ if (IS_I965G(dev))
851+ dev_priv->saveDPLL_B_MD = I915_READ(DPLL_B_MD);
852+ dev_priv->saveHTOTAL_B = I915_READ(HTOTAL_B);
853+ dev_priv->saveHBLANK_B = I915_READ(HBLANK_B);
854+ dev_priv->saveHSYNC_B = I915_READ(HSYNC_B);
855+ dev_priv->saveVTOTAL_B = I915_READ(VTOTAL_B);
856+ dev_priv->saveVBLANK_B = I915_READ(VBLANK_B);
857+ dev_priv->saveVSYNC_B = I915_READ(VSYNC_B);
858+ dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A);
859+
860+ dev_priv->saveDSPBCNTR = I915_READ(DSPBCNTR);
861+ dev_priv->saveDSPBSTRIDE = I915_READ(DSPBSTRIDE);
862+ dev_priv->saveDSPBSIZE = I915_READ(DSPBSIZE);
863+ dev_priv->saveDSPBPOS = I915_READ(DSPBPOS);
864+ dev_priv->saveDSPBADDR = I915_READ(DSPBADDR);
865+ if (IS_I965GM(dev) || IS_IGD_GM(dev)) {
866+ dev_priv->saveDSPBSURF = I915_READ(DSPBSURF);
867+ dev_priv->saveDSPBTILEOFF = I915_READ(DSPBTILEOFF);
868+ }
869+ i915_save_palette(dev, PIPE_B);
870+ dev_priv->savePIPEBSTAT = I915_READ(PIPEBSTAT);
871+
872+ /* CRT state */
873+ dev_priv->saveADPA = I915_READ(ADPA);
874+
875+ /* LVDS state */
876+ dev_priv->savePP_CONTROL = I915_READ(PP_CONTROL);
877+ dev_priv->savePFIT_PGM_RATIOS = I915_READ(PFIT_PGM_RATIOS);
878+ dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_CTL);
879+ if (IS_I965G(dev))
880+ dev_priv->saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_CTL2);
881+ if (IS_MOBILE(dev) && !IS_I830(dev))
882+ dev_priv->saveLVDS = I915_READ(LVDS);
883+ if (!IS_I830(dev) && !IS_845G(dev))
884+ dev_priv->savePFIT_CONTROL = I915_READ(PFIT_CONTROL);
885+ dev_priv->savePP_ON_DELAYS = I915_READ(PP_ON_DELAYS);
886+ dev_priv->savePP_OFF_DELAYS = I915_READ(PP_OFF_DELAYS);
887+ dev_priv->savePP_DIVISOR = I915_READ(PP_DIVISOR);
888+
889+ /* FIXME: save TV & SDVO state */
890+
891+ /* FBC state */
892+ dev_priv->saveFBC_CFB_BASE = I915_READ(FBC_CFB_BASE);
893+ dev_priv->saveFBC_LL_BASE = I915_READ(FBC_LL_BASE);
894+ dev_priv->saveFBC_CONTROL2 = I915_READ(FBC_CONTROL2);
895+ dev_priv->saveFBC_CONTROL = I915_READ(FBC_CONTROL);
896+
897+ /* Interrupt state */
898+ dev_priv->saveIIR = I915_READ(IIR);
899+ dev_priv->saveIER = I915_READ(IER);
900+ dev_priv->saveIMR = I915_READ(IMR);
901+
902+ /* VGA state */
903+ dev_priv->saveVGA0 = I915_READ(VGA0);
904+ dev_priv->saveVGA1 = I915_READ(VGA1);
905+ dev_priv->saveVGA_PD = I915_READ(VGA_PD);
906+ dev_priv->saveVGACNTRL = I915_READ(VGACNTRL);
907+
908+ /* Clock gating state */
909+ dev_priv->saveD_STATE = I915_READ(D_STATE);
910+ dev_priv->saveCG_2D_DIS = I915_READ(CG_2D_DIS);
911+
912+ /* Cache mode state */
913+ dev_priv->saveCACHE_MODE_0 = I915_READ(CACHE_MODE_0);
914+
915+ /* Memory Arbitration state */
916+ dev_priv->saveMI_ARB_STATE = I915_READ(MI_ARB_STATE);
917+
918+ /* Scratch space */
919+ for (i = 0; i < 16; i++) {
920+ dev_priv->saveSWF0[i] = I915_READ(SWF00 + (i << 2));
921+ dev_priv->saveSWF1[i] = I915_READ(SWF10 + (i << 2));
922+ }
923+ for (i = 0; i < 3; i++)
924+ dev_priv->saveSWF2[i] = I915_READ(SWF30 + (i << 2));
925+
926+ i915_save_vga(dev);
927+
928+ return 0;
929+}
930+
931+int i915_restore_state(struct drm_device *dev)
932+{
933+ struct drm_i915_private *dev_priv = dev->dev_private;
934+ int i;
935+
936+ pci_write_config_byte(dev->pdev, LBB, dev_priv->saveLBB);
937+
938+ I915_WRITE(DSPARB, dev_priv->saveDSPARB);
939+
940+ /* Pipe & plane A info */
941+ /* Prime the clock */
942+ if (dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) {
943+ I915_WRITE(DPLL_A, dev_priv->saveDPLL_A &
944+ ~DPLL_VCO_ENABLE);
945+ DRM_UDELAY(150);
946+ }
947+ I915_WRITE(FPA0, dev_priv->saveFPA0);
948+ I915_WRITE(FPA1, dev_priv->saveFPA1);
949+ /* Actually enable it */
950+ I915_WRITE(DPLL_A, dev_priv->saveDPLL_A);
951+ DRM_UDELAY(150);
952+ if (IS_I965G(dev))
953+ I915_WRITE(DPLL_A_MD, dev_priv->saveDPLL_A_MD);
954+ DRM_UDELAY(150);
955+
956+ /* Restore mode */
957+ I915_WRITE(HTOTAL_A, dev_priv->saveHTOTAL_A);
958+ I915_WRITE(HBLANK_A, dev_priv->saveHBLANK_A);
959+ I915_WRITE(HSYNC_A, dev_priv->saveHSYNC_A);
960+ I915_WRITE(VTOTAL_A, dev_priv->saveVTOTAL_A);
961+ I915_WRITE(VBLANK_A, dev_priv->saveVBLANK_A);
962+ I915_WRITE(VSYNC_A, dev_priv->saveVSYNC_A);
963+ I915_WRITE(BCLRPAT_A, dev_priv->saveBCLRPAT_A);
964+
965+ /* Restore plane info */
966+ I915_WRITE(DSPASIZE, dev_priv->saveDSPASIZE);
967+ I915_WRITE(DSPAPOS, dev_priv->saveDSPAPOS);
968+ I915_WRITE(PIPEASRC, dev_priv->savePIPEASRC);
969+ I915_WRITE(DSPAADDR, dev_priv->saveDSPAADDR);
970+ I915_WRITE(DSPASTRIDE, dev_priv->saveDSPASTRIDE);
971+ if (IS_I965G(dev)) {
972+ I915_WRITE(DSPASURF, dev_priv->saveDSPASURF);
973+ I915_WRITE(DSPATILEOFF, dev_priv->saveDSPATILEOFF);
974+ }
975+
976+ I915_WRITE(PIPEACONF, dev_priv->savePIPEACONF);
977+
978+ i915_restore_palette(dev, PIPE_A);
979+ /* Enable the plane */
980+ I915_WRITE(DSPACNTR, dev_priv->saveDSPACNTR);
981+ I915_WRITE(DSPAADDR, I915_READ(DSPAADDR));
982+
983+ /* Pipe & plane B info */
984+ if (dev_priv->saveDPLL_B & DPLL_VCO_ENABLE) {
985+ I915_WRITE(DPLL_B, dev_priv->saveDPLL_B &
986+ ~DPLL_VCO_ENABLE);
987+ DRM_UDELAY(150);
988+ }
989+ I915_WRITE(FPB0, dev_priv->saveFPB0);
990+ I915_WRITE(FPB1, dev_priv->saveFPB1);
991+ /* Actually enable it */
992+ I915_WRITE(DPLL_B, dev_priv->saveDPLL_B);
993+ DRM_UDELAY(150);
994+ if (IS_I965G(dev))
995+ I915_WRITE(DPLL_B_MD, dev_priv->saveDPLL_B_MD);
996+ DRM_UDELAY(150);
997+
998+ /* Restore mode */
999+ I915_WRITE(HTOTAL_B, dev_priv->saveHTOTAL_B);
1000+ I915_WRITE(HBLANK_B, dev_priv->saveHBLANK_B);
1001+ I915_WRITE(HSYNC_B, dev_priv->saveHSYNC_B);
1002+ I915_WRITE(VTOTAL_B, dev_priv->saveVTOTAL_B);
1003+ I915_WRITE(VBLANK_B, dev_priv->saveVBLANK_B);
1004+ I915_WRITE(VSYNC_B, dev_priv->saveVSYNC_B);
1005+ I915_WRITE(BCLRPAT_B, dev_priv->saveBCLRPAT_B);
1006+
1007+ /* Restore plane info */
1008+ I915_WRITE(DSPBSIZE, dev_priv->saveDSPBSIZE);
1009+ I915_WRITE(DSPBPOS, dev_priv->saveDSPBPOS);
1010+ I915_WRITE(PIPEBSRC, dev_priv->savePIPEBSRC);
1011+ I915_WRITE(DSPBADDR, dev_priv->saveDSPBADDR);
1012+ I915_WRITE(DSPBSTRIDE, dev_priv->saveDSPBSTRIDE);
1013+ if (IS_I965G(dev)) {
1014+ I915_WRITE(DSPBSURF, dev_priv->saveDSPBSURF);
1015+ I915_WRITE(DSPBTILEOFF, dev_priv->saveDSPBTILEOFF);
1016+ }
1017+
1018+ I915_WRITE(PIPEBCONF, dev_priv->savePIPEBCONF);
1019+
1020+ i915_restore_palette(dev, PIPE_B);
1021+ /* Enable the plane */
1022+ I915_WRITE(DSPBCNTR, dev_priv->saveDSPBCNTR);
1023+ I915_WRITE(DSPBADDR, I915_READ(DSPBADDR));
1024+
1025+ /* CRT state */
1026+ I915_WRITE(ADPA, dev_priv->saveADPA);
1027+
1028+ /* LVDS state */
1029+ if (IS_I965G(dev))
1030+ I915_WRITE(BLC_PWM_CTL2, dev_priv->saveBLC_PWM_CTL2);
1031+ if (IS_MOBILE(dev) && !IS_I830(dev))
1032+ I915_WRITE(LVDS, dev_priv->saveLVDS);
1033+ if (!IS_I830(dev) && !IS_845G(dev))
1034+ I915_WRITE(PFIT_CONTROL, dev_priv->savePFIT_CONTROL);
1035+
1036+ I915_WRITE(PFIT_PGM_RATIOS, dev_priv->savePFIT_PGM_RATIOS);
1037+ I915_WRITE(BLC_PWM_CTL, dev_priv->saveBLC_PWM_CTL);
1038+ I915_WRITE(PP_ON_DELAYS, dev_priv->savePP_ON_DELAYS);
1039+ I915_WRITE(PP_OFF_DELAYS, dev_priv->savePP_OFF_DELAYS);
1040+ I915_WRITE(PP_DIVISOR, dev_priv->savePP_DIVISOR);
1041+ I915_WRITE(PP_CONTROL, dev_priv->savePP_CONTROL);
1042+
1043+ /* FIXME: restore TV & SDVO state */
1044+
1045+ /* FBC info */
1046+ I915_WRITE(FBC_CFB_BASE, dev_priv->saveFBC_CFB_BASE);
1047+ I915_WRITE(FBC_LL_BASE, dev_priv->saveFBC_LL_BASE);
1048+ I915_WRITE(FBC_CONTROL2, dev_priv->saveFBC_CONTROL2);
1049+ I915_WRITE(FBC_CONTROL, dev_priv->saveFBC_CONTROL);
1050+
1051+ /* VGA state */
1052+ I915_WRITE(VGACNTRL, dev_priv->saveVGACNTRL);
1053+ I915_WRITE(VGA0, dev_priv->saveVGA0);
1054+ I915_WRITE(VGA1, dev_priv->saveVGA1);
1055+ I915_WRITE(VGA_PD, dev_priv->saveVGA_PD);
1056+ DRM_UDELAY(150);
1057+
1058+ /* Clock gating state */
1059+ I915_WRITE (D_STATE, dev_priv->saveD_STATE);
1060+ I915_WRITE (CG_2D_DIS, dev_priv->saveCG_2D_DIS);
1061+
1062+ /* Cache mode state */
1063+ I915_WRITE (CACHE_MODE_0, dev_priv->saveCACHE_MODE_0 | 0xffff0000);
1064+
1065+ /* Memory arbitration state */
1066+ I915_WRITE (MI_ARB_STATE, dev_priv->saveMI_ARB_STATE | 0xffff0000);
1067+
1068+ for (i = 0; i < 16; i++) {
1069+ I915_WRITE(SWF00 + (i << 2), dev_priv->saveSWF0[i]);
1070+ I915_WRITE(SWF10 + (i << 2), dev_priv->saveSWF1[i+7]);
1071+ }
1072+ for (i = 0; i < 3; i++)
1073+ I915_WRITE(SWF30 + (i << 2), dev_priv->saveSWF2[i]);
1074+
1075+ i915_restore_vga(dev);
1076+
1077+ return 0;
1078+}
1079+
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27/0011-drm-vblank-rework.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27/0011-drm-vblank-rework.patch
new file mode 100644
index 0000000000..6161a71f04
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27/0011-drm-vblank-rework.patch
@@ -0,0 +1,1534 @@
1commit 2aebb4e4e62d09b4a95be7be7c24a7f6528385b7
2Author: Jesse Barnes <jbarnes@virtuousgeek.org>
3Date: Tue Sep 30 12:14:26 2008 -0700
4
5 drm: Rework vblank-wait handling to allow interrupt reduction.
6
7 Previously, drivers supporting vblank interrupt waits would run the interrupt
8 all the time, or all the time that any 3d client was running, preventing the
9 CPU from sleeping for long when the system was otherwise idle. Now, interrupts
10 are disabled any time that no client is waiting on a vblank event. The new
11 method uses vblank counters on the chipsets when the interrupts are turned
12 off, rather than counting interrupts, so that we can continue to present
13 accurate vblank numbers.
14
15 Co-author: Michel Dänzer <michel@tungstengraphics.com>
16 Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
17 Signed-off-by: Eric Anholt <eric@anholt.net>
18 Signed-off-by: Dave Airlie <airlied@redhat.com>
19
20diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
21index 452c2d8..fb45fe7 100644
22--- a/drivers/gpu/drm/drm_drv.c
23+++ b/drivers/gpu/drm/drm_drv.c
24@@ -116,6 +116,8 @@ static struct drm_ioctl_desc drm_ioctls[] = {
25
26 DRM_IOCTL_DEF(DRM_IOCTL_WAIT_VBLANK, drm_wait_vblank, 0),
27
28+ DRM_IOCTL_DEF(DRM_IOCTL_MODESET_CTL, drm_modeset_ctl, 0),
29+
30 DRM_IOCTL_DEF(DRM_IOCTL_UPDATE_DRAW, drm_update_drawable_info, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
31 };
32
33diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
34index 61ed515..d0c13d9 100644
35--- a/drivers/gpu/drm/drm_irq.c
36+++ b/drivers/gpu/drm/drm_irq.c
37@@ -71,19 +71,131 @@ int drm_irq_by_busid(struct drm_device *dev, void *data,
38 return 0;
39 }
40
41+static void vblank_disable_fn(unsigned long arg)
42+{
43+ struct drm_device *dev = (struct drm_device *)arg;
44+ unsigned long irqflags;
45+ int i;
46+
47+ if (!dev->vblank_disable_allowed)
48+ return;
49+
50+ for (i = 0; i < dev->num_crtcs; i++) {
51+ spin_lock_irqsave(&dev->vbl_lock, irqflags);
52+ if (atomic_read(&dev->vblank_refcount[i]) == 0 &&
53+ dev->vblank_enabled[i]) {
54+ DRM_DEBUG("disabling vblank on crtc %d\n", i);
55+ dev->last_vblank[i] =
56+ dev->driver->get_vblank_counter(dev, i);
57+ dev->driver->disable_vblank(dev, i);
58+ dev->vblank_enabled[i] = 0;
59+ }
60+ spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
61+ }
62+}
63+
64+static void drm_vblank_cleanup(struct drm_device *dev)
65+{
66+ /* Bail if the driver didn't call drm_vblank_init() */
67+ if (dev->num_crtcs == 0)
68+ return;
69+
70+ del_timer(&dev->vblank_disable_timer);
71+
72+ vblank_disable_fn((unsigned long)dev);
73+
74+ drm_free(dev->vbl_queue, sizeof(*dev->vbl_queue) * dev->num_crtcs,
75+ DRM_MEM_DRIVER);
76+ drm_free(dev->vbl_sigs, sizeof(*dev->vbl_sigs) * dev->num_crtcs,
77+ DRM_MEM_DRIVER);
78+ drm_free(dev->_vblank_count, sizeof(*dev->_vblank_count) *
79+ dev->num_crtcs, DRM_MEM_DRIVER);
80+ drm_free(dev->vblank_refcount, sizeof(*dev->vblank_refcount) *
81+ dev->num_crtcs, DRM_MEM_DRIVER);
82+ drm_free(dev->vblank_enabled, sizeof(*dev->vblank_enabled) *
83+ dev->num_crtcs, DRM_MEM_DRIVER);
84+ drm_free(dev->last_vblank, sizeof(*dev->last_vblank) * dev->num_crtcs,
85+ DRM_MEM_DRIVER);
86+ drm_free(dev->vblank_inmodeset, sizeof(*dev->vblank_inmodeset) *
87+ dev->num_crtcs, DRM_MEM_DRIVER);
88+
89+ dev->num_crtcs = 0;
90+}
91+
92+int drm_vblank_init(struct drm_device *dev, int num_crtcs)
93+{
94+ int i, ret = -ENOMEM;
95+
96+ setup_timer(&dev->vblank_disable_timer, vblank_disable_fn,
97+ (unsigned long)dev);
98+ spin_lock_init(&dev->vbl_lock);
99+ atomic_set(&dev->vbl_signal_pending, 0);
100+ dev->num_crtcs = num_crtcs;
101+
102+ dev->vbl_queue = drm_alloc(sizeof(wait_queue_head_t) * num_crtcs,
103+ DRM_MEM_DRIVER);
104+ if (!dev->vbl_queue)
105+ goto err;
106+
107+ dev->vbl_sigs = drm_alloc(sizeof(struct list_head) * num_crtcs,
108+ DRM_MEM_DRIVER);
109+ if (!dev->vbl_sigs)
110+ goto err;
111+
112+ dev->_vblank_count = drm_alloc(sizeof(atomic_t) * num_crtcs,
113+ DRM_MEM_DRIVER);
114+ if (!dev->_vblank_count)
115+ goto err;
116+
117+ dev->vblank_refcount = drm_alloc(sizeof(atomic_t) * num_crtcs,
118+ DRM_MEM_DRIVER);
119+ if (!dev->vblank_refcount)
120+ goto err;
121+
122+ dev->vblank_enabled = drm_calloc(num_crtcs, sizeof(int),
123+ DRM_MEM_DRIVER);
124+ if (!dev->vblank_enabled)
125+ goto err;
126+
127+ dev->last_vblank = drm_calloc(num_crtcs, sizeof(u32), DRM_MEM_DRIVER);
128+ if (!dev->last_vblank)
129+ goto err;
130+
131+ dev->vblank_inmodeset = drm_calloc(num_crtcs, sizeof(int),
132+ DRM_MEM_DRIVER);
133+ if (!dev->vblank_inmodeset)
134+ goto err;
135+
136+ /* Zero per-crtc vblank stuff */
137+ for (i = 0; i < num_crtcs; i++) {
138+ init_waitqueue_head(&dev->vbl_queue[i]);
139+ INIT_LIST_HEAD(&dev->vbl_sigs[i]);
140+ atomic_set(&dev->_vblank_count[i], 0);
141+ atomic_set(&dev->vblank_refcount[i], 0);
142+ }
143+
144+ dev->vblank_disable_allowed = 0;
145+
146+ return 0;
147+
148+err:
149+ drm_vblank_cleanup(dev);
150+ return ret;
151+}
152+EXPORT_SYMBOL(drm_vblank_init);
153+
154 /**
155 * Install IRQ handler.
156 *
157 * \param dev DRM device.
158- * \param irq IRQ number.
159 *
160- * Initializes the IRQ related data, and setups drm_device::vbl_queue. Installs the handler, calling the driver
161+ * Initializes the IRQ related data. Installs the handler, calling the driver
162 * \c drm_driver_irq_preinstall() and \c drm_driver_irq_postinstall() functions
163 * before and after the installation.
164 */
165-static int drm_irq_install(struct drm_device * dev)
166+int drm_irq_install(struct drm_device *dev)
167 {
168- int ret;
169+ int ret = 0;
170 unsigned long sh_flags = 0;
171
172 if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
173@@ -109,17 +221,6 @@ static int drm_irq_install(struct drm_device * dev)
174
175 DRM_DEBUG("irq=%d\n", dev->pdev->irq);
176
177- if (drm_core_check_feature(dev, DRIVER_IRQ_VBL)) {
178- init_waitqueue_head(&dev->vbl_queue);
179-
180- spin_lock_init(&dev->vbl_lock);
181-
182- INIT_LIST_HEAD(&dev->vbl_sigs);
183- INIT_LIST_HEAD(&dev->vbl_sigs2);
184-
185- dev->vbl_pending = 0;
186- }
187-
188 /* Before installing handler */
189 dev->driver->irq_preinstall(dev);
190
191@@ -141,10 +242,16 @@ static int drm_irq_install(struct drm_device * dev)
192 }
193
194 /* After installing handler */
195- dev->driver->irq_postinstall(dev);
196+ ret = dev->driver->irq_postinstall(dev);
197+ if (ret < 0) {
198+ mutex_lock(&dev->struct_mutex);
199+ dev->irq_enabled = 0;
200+ mutex_unlock(&dev->struct_mutex);
201+ }
202
203- return 0;
204+ return ret;
205 }
206+EXPORT_SYMBOL(drm_irq_install);
207
208 /**
209 * Uninstall the IRQ handler.
210@@ -174,11 +281,12 @@ int drm_irq_uninstall(struct drm_device * dev)
211
212 free_irq(dev->pdev->irq, dev);
213
214+ drm_vblank_cleanup(dev);
215+
216 dev->locked_tasklet_func = NULL;
217
218 return 0;
219 }
220-
221 EXPORT_SYMBOL(drm_irq_uninstall);
222
223 /**
224@@ -218,6 +326,174 @@ int drm_control(struct drm_device *dev, void *data,
225 }
226
227 /**
228+ * drm_vblank_count - retrieve "cooked" vblank counter value
229+ * @dev: DRM device
230+ * @crtc: which counter to retrieve
231+ *
232+ * Fetches the "cooked" vblank count value that represents the number of
233+ * vblank events since the system was booted, including lost events due to
234+ * modesetting activity.
235+ */
236+u32 drm_vblank_count(struct drm_device *dev, int crtc)
237+{
238+ return atomic_read(&dev->_vblank_count[crtc]);
239+}
240+EXPORT_SYMBOL(drm_vblank_count);
241+
242+/**
243+ * drm_update_vblank_count - update the master vblank counter
244+ * @dev: DRM device
245+ * @crtc: counter to update
246+ *
247+ * Call back into the driver to update the appropriate vblank counter
248+ * (specified by @crtc). Deal with wraparound, if it occurred, and
249+ * update the last read value so we can deal with wraparound on the next
250+ * call if necessary.
251+ *
252+ * Only necessary when going from off->on, to account for frames we
253+ * didn't get an interrupt for.
254+ *
255+ * Note: caller must hold dev->vbl_lock since this reads & writes
256+ * device vblank fields.
257+ */
258+static void drm_update_vblank_count(struct drm_device *dev, int crtc)
259+{
260+ u32 cur_vblank, diff;
261+
262+ /*
263+ * Interrupts were disabled prior to this call, so deal with counter
264+ * wrap if needed.
265+ * NOTE! It's possible we lost a full dev->max_vblank_count events
266+ * here if the register is small or we had vblank interrupts off for
267+ * a long time.
268+ */
269+ cur_vblank = dev->driver->get_vblank_counter(dev, crtc);
270+ diff = cur_vblank - dev->last_vblank[crtc];
271+ if (cur_vblank < dev->last_vblank[crtc]) {
272+ diff += dev->max_vblank_count;
273+
274+ DRM_DEBUG("last_vblank[%d]=0x%x, cur_vblank=0x%x => diff=0x%x\n",
275+ crtc, dev->last_vblank[crtc], cur_vblank, diff);
276+ }
277+
278+ DRM_DEBUG("enabling vblank interrupts on crtc %d, missed %d\n",
279+ crtc, diff);
280+
281+ atomic_add(diff, &dev->_vblank_count[crtc]);
282+}
283+
284+/**
285+ * drm_vblank_get - get a reference count on vblank events
286+ * @dev: DRM device
287+ * @crtc: which CRTC to own
288+ *
289+ * Acquire a reference count on vblank events to avoid having them disabled
290+ * while in use.
291+ *
292+ * RETURNS
293+ * Zero on success, nonzero on failure.
294+ */
295+int drm_vblank_get(struct drm_device *dev, int crtc)
296+{
297+ unsigned long irqflags;
298+ int ret = 0;
299+
300+ spin_lock_irqsave(&dev->vbl_lock, irqflags);
301+ /* Going from 0->1 means we have to enable interrupts again */
302+ if (atomic_add_return(1, &dev->vblank_refcount[crtc]) == 1 &&
303+ !dev->vblank_enabled[crtc]) {
304+ ret = dev->driver->enable_vblank(dev, crtc);
305+ DRM_DEBUG("enabling vblank on crtc %d, ret: %d\n", crtc, ret);
306+ if (ret)
307+ atomic_dec(&dev->vblank_refcount[crtc]);
308+ else {
309+ dev->vblank_enabled[crtc] = 1;
310+ drm_update_vblank_count(dev, crtc);
311+ }
312+ }
313+ spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
314+
315+ return ret;
316+}
317+EXPORT_SYMBOL(drm_vblank_get);
318+
319+/**
320+ * drm_vblank_put - give up ownership of vblank events
321+ * @dev: DRM device
322+ * @crtc: which counter to give up
323+ *
324+ * Release ownership of a given vblank counter, turning off interrupts
325+ * if possible.
326+ */
327+void drm_vblank_put(struct drm_device *dev, int crtc)
328+{
329+ /* Last user schedules interrupt disable */
330+ if (atomic_dec_and_test(&dev->vblank_refcount[crtc]))
331+ mod_timer(&dev->vblank_disable_timer, jiffies + 5*DRM_HZ);
332+}
333+EXPORT_SYMBOL(drm_vblank_put);
334+
335+/**
336+ * drm_modeset_ctl - handle vblank event counter changes across mode switch
337+ * @DRM_IOCTL_ARGS: standard ioctl arguments
338+ *
339+ * Applications should call the %_DRM_PRE_MODESET and %_DRM_POST_MODESET
340+ * ioctls around modesetting so that any lost vblank events are accounted for.
341+ *
342+ * Generally the counter will reset across mode sets. If interrupts are
343+ * enabled around this call, we don't have to do anything since the counter
344+ * will have already been incremented.
345+ */
346+int drm_modeset_ctl(struct drm_device *dev, void *data,
347+ struct drm_file *file_priv)
348+{
349+ struct drm_modeset_ctl *modeset = data;
350+ unsigned long irqflags;
351+ int crtc, ret = 0;
352+
353+ /* If drm_vblank_init() hasn't been called yet, just no-op */
354+ if (!dev->num_crtcs)
355+ goto out;
356+
357+ crtc = modeset->crtc;
358+ if (crtc >= dev->num_crtcs) {
359+ ret = -EINVAL;
360+ goto out;
361+ }
362+
363+ /*
364+ * To avoid all the problems that might happen if interrupts
365+ * were enabled/disabled around or between these calls, we just
366+ * have the kernel take a reference on the CRTC (just once though
367+ * to avoid corrupting the count if multiple, mismatch calls occur),
368+ * so that interrupts remain enabled in the interim.
369+ */
370+ switch (modeset->cmd) {
371+ case _DRM_PRE_MODESET:
372+ if (!dev->vblank_inmodeset[crtc]) {
373+ dev->vblank_inmodeset[crtc] = 1;
374+ drm_vblank_get(dev, crtc);
375+ }
376+ break;
377+ case _DRM_POST_MODESET:
378+ if (dev->vblank_inmodeset[crtc]) {
379+ spin_lock_irqsave(&dev->vbl_lock, irqflags);
380+ dev->vblank_disable_allowed = 1;
381+ dev->vblank_inmodeset[crtc] = 0;
382+ spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
383+ drm_vblank_put(dev, crtc);
384+ }
385+ break;
386+ default:
387+ ret = -EINVAL;
388+ break;
389+ }
390+
391+out:
392+ return ret;
393+}
394+
395+/**
396 * Wait for VBLANK.
397 *
398 * \param inode device inode.
399@@ -236,12 +512,12 @@ int drm_control(struct drm_device *dev, void *data,
400 *
401 * If a signal is not requested, then calls vblank_wait().
402 */
403-int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_priv)
404+int drm_wait_vblank(struct drm_device *dev, void *data,
405+ struct drm_file *file_priv)
406 {
407 union drm_wait_vblank *vblwait = data;
408- struct timeval now;
409 int ret = 0;
410- unsigned int flags, seq;
411+ unsigned int flags, seq, crtc;
412
413 if ((!dev->pdev->irq) || (!dev->irq_enabled))
414 return -EINVAL;
415@@ -255,13 +531,17 @@ int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_pr
416 }
417
418 flags = vblwait->request.type & _DRM_VBLANK_FLAGS_MASK;
419+ crtc = flags & _DRM_VBLANK_SECONDARY ? 1 : 0;
420
421- if (!drm_core_check_feature(dev, (flags & _DRM_VBLANK_SECONDARY) ?
422- DRIVER_IRQ_VBL2 : DRIVER_IRQ_VBL))
423+ if (crtc >= dev->num_crtcs)
424 return -EINVAL;
425
426- seq = atomic_read((flags & _DRM_VBLANK_SECONDARY) ? &dev->vbl_received2
427- : &dev->vbl_received);
428+ ret = drm_vblank_get(dev, crtc);
429+ if (ret) {
430+ DRM_ERROR("failed to acquire vblank counter, %d\n", ret);
431+ return ret;
432+ }
433+ seq = drm_vblank_count(dev, crtc);
434
435 switch (vblwait->request.type & _DRM_VBLANK_TYPES_MASK) {
436 case _DRM_VBLANK_RELATIVE:
437@@ -270,7 +550,8 @@ int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_pr
438 case _DRM_VBLANK_ABSOLUTE:
439 break;
440 default:
441- return -EINVAL;
442+ ret = -EINVAL;
443+ goto done;
444 }
445
446 if ((flags & _DRM_VBLANK_NEXTONMISS) &&
447@@ -280,8 +561,7 @@ int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_pr
448
449 if (flags & _DRM_VBLANK_SIGNAL) {
450 unsigned long irqflags;
451- struct list_head *vbl_sigs = (flags & _DRM_VBLANK_SECONDARY)
452- ? &dev->vbl_sigs2 : &dev->vbl_sigs;
453+ struct list_head *vbl_sigs = &dev->vbl_sigs[crtc];
454 struct drm_vbl_sig *vbl_sig;
455
456 spin_lock_irqsave(&dev->vbl_lock, irqflags);
457@@ -302,22 +582,29 @@ int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_pr
458 }
459 }
460
461- if (dev->vbl_pending >= 100) {
462+ if (atomic_read(&dev->vbl_signal_pending) >= 100) {
463 spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
464- return -EBUSY;
465+ ret = -EBUSY;
466+ goto done;
467 }
468
469- dev->vbl_pending++;
470-
471 spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
472
473- if (!
474- (vbl_sig =
475- drm_alloc(sizeof(struct drm_vbl_sig), DRM_MEM_DRIVER))) {
476- return -ENOMEM;
477+ vbl_sig = drm_calloc(1, sizeof(struct drm_vbl_sig),
478+ DRM_MEM_DRIVER);
479+ if (!vbl_sig) {
480+ ret = -ENOMEM;
481+ goto done;
482+ }
483+
484+ ret = drm_vblank_get(dev, crtc);
485+ if (ret) {
486+ drm_free(vbl_sig, sizeof(struct drm_vbl_sig),
487+ DRM_MEM_DRIVER);
488+ return ret;
489 }
490
491- memset((void *)vbl_sig, 0, sizeof(*vbl_sig));
492+ atomic_inc(&dev->vbl_signal_pending);
493
494 vbl_sig->sequence = vblwait->request.sequence;
495 vbl_sig->info.si_signo = vblwait->request.signal;
496@@ -331,20 +618,29 @@ int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_pr
497
498 vblwait->reply.sequence = seq;
499 } else {
500- if (flags & _DRM_VBLANK_SECONDARY) {
501- if (dev->driver->vblank_wait2)
502- ret = dev->driver->vblank_wait2(dev, &vblwait->request.sequence);
503- } else if (dev->driver->vblank_wait)
504- ret =
505- dev->driver->vblank_wait(dev,
506- &vblwait->request.sequence);
507-
508- do_gettimeofday(&now);
509- vblwait->reply.tval_sec = now.tv_sec;
510- vblwait->reply.tval_usec = now.tv_usec;
511+ DRM_DEBUG("waiting on vblank count %d, crtc %d\n",
512+ vblwait->request.sequence, crtc);
513+ DRM_WAIT_ON(ret, dev->vbl_queue[crtc], 3 * DRM_HZ,
514+ ((drm_vblank_count(dev, crtc)
515+ - vblwait->request.sequence) <= (1 << 23)));
516+
517+ if (ret != -EINTR) {
518+ struct timeval now;
519+
520+ do_gettimeofday(&now);
521+
522+ vblwait->reply.tval_sec = now.tv_sec;
523+ vblwait->reply.tval_usec = now.tv_usec;
524+ vblwait->reply.sequence = drm_vblank_count(dev, crtc);
525+ DRM_DEBUG("returning %d to client\n",
526+ vblwait->reply.sequence);
527+ } else {
528+ DRM_DEBUG("vblank wait interrupted by signal\n");
529+ }
530 }
531
532- done:
533+done:
534+ drm_vblank_put(dev, crtc);
535 return ret;
536 }
537
538@@ -352,44 +648,57 @@ int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_pr
539 * Send the VBLANK signals.
540 *
541 * \param dev DRM device.
542+ * \param crtc CRTC where the vblank event occurred
543 *
544 * Sends a signal for each task in drm_device::vbl_sigs and empties the list.
545 *
546 * If a signal is not requested, then calls vblank_wait().
547 */
548-void drm_vbl_send_signals(struct drm_device * dev)
549+static void drm_vbl_send_signals(struct drm_device *dev, int crtc)
550 {
551+ struct drm_vbl_sig *vbl_sig, *tmp;
552+ struct list_head *vbl_sigs;
553+ unsigned int vbl_seq;
554 unsigned long flags;
555- int i;
556
557 spin_lock_irqsave(&dev->vbl_lock, flags);
558
559- for (i = 0; i < 2; i++) {
560- struct drm_vbl_sig *vbl_sig, *tmp;
561- struct list_head *vbl_sigs = i ? &dev->vbl_sigs2 : &dev->vbl_sigs;
562- unsigned int vbl_seq = atomic_read(i ? &dev->vbl_received2 :
563- &dev->vbl_received);
564+ vbl_sigs = &dev->vbl_sigs[crtc];
565+ vbl_seq = drm_vblank_count(dev, crtc);
566
567- list_for_each_entry_safe(vbl_sig, tmp, vbl_sigs, head) {
568- if ((vbl_seq - vbl_sig->sequence) <= (1 << 23)) {
569- vbl_sig->info.si_code = vbl_seq;
570- send_sig_info(vbl_sig->info.si_signo,
571- &vbl_sig->info, vbl_sig->task);
572+ list_for_each_entry_safe(vbl_sig, tmp, vbl_sigs, head) {
573+ if ((vbl_seq - vbl_sig->sequence) <= (1 << 23)) {
574+ vbl_sig->info.si_code = vbl_seq;
575+ send_sig_info(vbl_sig->info.si_signo,
576+ &vbl_sig->info, vbl_sig->task);
577
578- list_del(&vbl_sig->head);
579-
580- drm_free(vbl_sig, sizeof(*vbl_sig),
581- DRM_MEM_DRIVER);
582+ list_del(&vbl_sig->head);
583
584- dev->vbl_pending--;
585- }
586- }
587+ drm_free(vbl_sig, sizeof(*vbl_sig),
588+ DRM_MEM_DRIVER);
589+ atomic_dec(&dev->vbl_signal_pending);
590+ drm_vblank_put(dev, crtc);
591+ }
592 }
593
594 spin_unlock_irqrestore(&dev->vbl_lock, flags);
595 }
596
597-EXPORT_SYMBOL(drm_vbl_send_signals);
598+/**
599+ * drm_handle_vblank - handle a vblank event
600+ * @dev: DRM device
601+ * @crtc: where this event occurred
602+ *
603+ * Drivers should call this routine in their vblank interrupt handlers to
604+ * update the vblank counter and send any signals that may be pending.
605+ */
606+void drm_handle_vblank(struct drm_device *dev, int crtc)
607+{
608+ atomic_inc(&dev->_vblank_count[crtc]);
609+ DRM_WAKEUP(&dev->vbl_queue[crtc]);
610+ drm_vbl_send_signals(dev, crtc);
611+}
612+EXPORT_SYMBOL(drm_handle_vblank);
613
614 /**
615 * Tasklet wrapper function.
616diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
617index cead62f..8609ec2 100644
618--- a/drivers/gpu/drm/i915/i915_dma.c
619+++ b/drivers/gpu/drm/i915/i915_dma.c
620@@ -673,7 +673,7 @@ static int i915_getparam(struct drm_device *dev, void *data,
621
622 switch (param->param) {
623 case I915_PARAM_IRQ_ACTIVE:
624- value = dev->irq_enabled;
625+ value = dev->pdev->irq ? 1 : 0;
626 break;
627 case I915_PARAM_ALLOW_BATCHBUFFER:
628 value = dev_priv->allow_batchbuffer ? 1 : 0;
629@@ -808,7 +808,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
630 * and the registers being closely associated.
631 */
632 if (!IS_I945G(dev) && !IS_I945GM(dev))
633- pci_enable_msi(dev->pdev);
634+ if (pci_enable_msi(dev->pdev))
635+ DRM_ERROR("failed to enable MSI\n");
636
637 intel_opregion_init(dev);
638
639diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
640index eff66ed..37af03f 100644
641--- a/drivers/gpu/drm/i915/i915_drv.c
642+++ b/drivers/gpu/drm/i915/i915_drv.c
643@@ -85,10 +85,8 @@ static struct drm_driver driver = {
644 /* don't use mtrr's here, the Xserver or user space app should
645 * deal with them for intel hardware.
646 */
647- .driver_features =
648- DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | /* DRIVER_USE_MTRR |*/
649- DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL |
650- DRIVER_IRQ_VBL2,
651+ .driver_features = DRIVER_USE_AGP | DRIVER_REQUIRE_AGP |
652+ DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED,
653 .load = i915_driver_load,
654 .unload = i915_driver_unload,
655 .lastclose = i915_driver_lastclose,
656@@ -96,8 +94,9 @@ static struct drm_driver driver = {
657 .suspend = i915_suspend,
658 .resume = i915_resume,
659 .device_is_agp = i915_driver_device_is_agp,
660- .vblank_wait = i915_driver_vblank_wait,
661- .vblank_wait2 = i915_driver_vblank_wait2,
662+ .get_vblank_counter = i915_get_vblank_counter,
663+ .enable_vblank = i915_enable_vblank,
664+ .disable_vblank = i915_disable_vblank,
665 .irq_preinstall = i915_driver_irq_preinstall,
666 .irq_postinstall = i915_driver_irq_postinstall,
667 .irq_uninstall = i915_driver_irq_uninstall,
668diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
669index 71326ca..d1a02be 100644
670--- a/drivers/gpu/drm/i915/i915_drv.h
671+++ b/drivers/gpu/drm/i915/i915_drv.h
672@@ -83,10 +83,15 @@ struct mem_block {
673 typedef struct _drm_i915_vbl_swap {
674 struct list_head head;
675 drm_drawable_t drw_id;
676- unsigned int pipe;
677+ unsigned int plane;
678 unsigned int sequence;
679 } drm_i915_vbl_swap_t;
680
681+struct opregion_header;
682+struct opregion_acpi;
683+struct opregion_swsci;
684+struct opregion_asle;
685+
686 struct intel_opregion {
687 struct opregion_header *header;
688 struct opregion_acpi *acpi;
689@@ -105,7 +110,7 @@ typedef struct drm_i915_private {
690 drm_dma_handle_t *status_page_dmah;
691 void *hw_status_page;
692 dma_addr_t dma_status_page;
693- unsigned long counter;
694+ uint32_t counter;
695 unsigned int status_gfx_addr;
696 drm_local_map_t hws_map;
697
698@@ -247,16 +252,17 @@ extern int i915_irq_emit(struct drm_device *dev, void *data,
699 extern int i915_irq_wait(struct drm_device *dev, void *data,
700 struct drm_file *file_priv);
701
702-extern int i915_driver_vblank_wait(struct drm_device *dev, unsigned int *sequence);
703-extern int i915_driver_vblank_wait2(struct drm_device *dev, unsigned int *sequence);
704 extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS);
705 extern void i915_driver_irq_preinstall(struct drm_device * dev);
706-extern void i915_driver_irq_postinstall(struct drm_device * dev);
707+extern int i915_driver_irq_postinstall(struct drm_device *dev);
708 extern void i915_driver_irq_uninstall(struct drm_device * dev);
709 extern int i915_vblank_pipe_set(struct drm_device *dev, void *data,
710 struct drm_file *file_priv);
711 extern int i915_vblank_pipe_get(struct drm_device *dev, void *data,
712 struct drm_file *file_priv);
713+extern int i915_enable_vblank(struct drm_device *dev, int crtc);
714+extern void i915_disable_vblank(struct drm_device *dev, int crtc);
715+extern u32 i915_get_vblank_counter(struct drm_device *dev, int crtc);
716 extern int i915_vblank_swap(struct drm_device *dev, void *data,
717 struct drm_file *file_priv);
718 extern void i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask);
719@@ -278,6 +284,10 @@ extern void i915_mem_release(struct drm_device * dev,
720 extern int i915_save_state(struct drm_device *dev);
721 extern int i915_restore_state(struct drm_device *dev);
722
723+/* i915_suspend.c */
724+extern int i915_save_state(struct drm_device *dev);
725+extern int i915_restore_state(struct drm_device *dev);
726+
727 /* i915_opregion.c */
728 extern int intel_opregion_init(struct drm_device *dev);
729 extern void intel_opregion_free(struct drm_device *dev);
730diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
731index ae7d3a8..f875959 100644
732--- a/drivers/gpu/drm/i915/i915_irq.c
733+++ b/drivers/gpu/drm/i915/i915_irq.c
734@@ -35,9 +35,8 @@
735
736 /** These are the interrupts used by the driver */
737 #define I915_INTERRUPT_ENABLE_MASK (I915_USER_INTERRUPT | \
738- I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT | \
739- I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT | \
740 I915_ASLE_INTERRUPT | \
741+ I915_DISPLAY_PIPE_A_EVENT_INTERRUPT | \
742 I915_DISPLAY_PIPE_B_EVENT_INTERRUPT)
743
744 void
745@@ -61,6 +60,64 @@ i915_disable_irq(drm_i915_private_t *dev_priv, u32 mask)
746 }
747
748 /**
749+ * i915_get_pipe - return the the pipe associated with a given plane
750+ * @dev: DRM device
751+ * @plane: plane to look for
752+ *
753+ * The Intel Mesa & 2D drivers call the vblank routines with a plane number
754+ * rather than a pipe number, since they may not always be equal. This routine
755+ * maps the given @plane back to a pipe number.
756+ */
757+static int
758+i915_get_pipe(struct drm_device *dev, int plane)
759+{
760+ drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
761+ u32 dspcntr;
762+
763+ dspcntr = plane ? I915_READ(DSPBCNTR) : I915_READ(DSPACNTR);
764+
765+ return dspcntr & DISPPLANE_SEL_PIPE_MASK ? 1 : 0;
766+}
767+
768+/**
769+ * i915_get_plane - return the the plane associated with a given pipe
770+ * @dev: DRM device
771+ * @pipe: pipe to look for
772+ *
773+ * The Intel Mesa & 2D drivers call the vblank routines with a plane number
774+ * rather than a plane number, since they may not always be equal. This routine
775+ * maps the given @pipe back to a plane number.
776+ */
777+static int
778+i915_get_plane(struct drm_device *dev, int pipe)
779+{
780+ if (i915_get_pipe(dev, 0) == pipe)
781+ return 0;
782+ return 1;
783+}
784+
785+/**
786+ * i915_pipe_enabled - check if a pipe is enabled
787+ * @dev: DRM device
788+ * @pipe: pipe to check
789+ *
790+ * Reading certain registers when the pipe is disabled can hang the chip.
791+ * Use this routine to make sure the PLL is running and the pipe is active
792+ * before reading such registers if unsure.
793+ */
794+static int
795+i915_pipe_enabled(struct drm_device *dev, int pipe)
796+{
797+ drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
798+ unsigned long pipeconf = pipe ? PIPEBCONF : PIPEACONF;
799+
800+ if (I915_READ(pipeconf) & PIPEACONF_ENABLE)
801+ return 1;
802+
803+ return 0;
804+}
805+
806+/**
807 * Emit blits for scheduled buffer swaps.
808 *
809 * This function will be called with the HW lock held.
810@@ -71,8 +128,7 @@ static void i915_vblank_tasklet(struct drm_device *dev)
811 unsigned long irqflags;
812 struct list_head *list, *tmp, hits, *hit;
813 int nhits, nrects, slice[2], upper[2], lower[2], i;
814- unsigned counter[2] = { atomic_read(&dev->vbl_received),
815- atomic_read(&dev->vbl_received2) };
816+ unsigned counter[2];
817 struct drm_drawable_info *drw;
818 drm_i915_sarea_t *sarea_priv = dev_priv->sarea_priv;
819 u32 cpp = dev_priv->cpp;
820@@ -94,6 +150,9 @@ static void i915_vblank_tasklet(struct drm_device *dev)
821 src_pitch >>= 2;
822 }
823
824+ counter[0] = drm_vblank_count(dev, 0);
825+ counter[1] = drm_vblank_count(dev, 1);
826+
827 DRM_DEBUG("\n");
828
829 INIT_LIST_HEAD(&hits);
830@@ -106,12 +165,14 @@ static void i915_vblank_tasklet(struct drm_device *dev)
831 list_for_each_safe(list, tmp, &dev_priv->vbl_swaps.head) {
832 drm_i915_vbl_swap_t *vbl_swap =
833 list_entry(list, drm_i915_vbl_swap_t, head);
834+ int pipe = i915_get_pipe(dev, vbl_swap->plane);
835
836- if ((counter[vbl_swap->pipe] - vbl_swap->sequence) > (1<<23))
837+ if ((counter[pipe] - vbl_swap->sequence) > (1<<23))
838 continue;
839
840 list_del(list);
841 dev_priv->swaps_pending--;
842+ drm_vblank_put(dev, pipe);
843
844 spin_unlock(&dev_priv->swaps_lock);
845 spin_lock(&dev->drw_lock);
846@@ -204,7 +265,7 @@ static void i915_vblank_tasklet(struct drm_device *dev)
847 drm_i915_vbl_swap_t *swap_hit =
848 list_entry(hit, drm_i915_vbl_swap_t, head);
849 struct drm_clip_rect *rect;
850- int num_rects, pipe;
851+ int num_rects, plane;
852 unsigned short top, bottom;
853
854 drw = drm_get_drawable_info(dev, swap_hit->drw_id);
855@@ -213,9 +274,9 @@ static void i915_vblank_tasklet(struct drm_device *dev)
856 continue;
857
858 rect = drw->rects;
859- pipe = swap_hit->pipe;
860- top = upper[pipe];
861- bottom = lower[pipe];
862+ plane = swap_hit->plane;
863+ top = upper[plane];
864+ bottom = lower[plane];
865
866 for (num_rects = drw->num_rects; num_rects--; rect++) {
867 int y1 = max(rect->y1, top);
868@@ -252,22 +313,54 @@ static void i915_vblank_tasklet(struct drm_device *dev)
869 }
870 }
871
872+u32 i915_get_vblank_counter(struct drm_device *dev, int plane)
873+{
874+ drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
875+ unsigned long high_frame;
876+ unsigned long low_frame;
877+ u32 high1, high2, low, count;
878+ int pipe;
879+
880+ pipe = i915_get_pipe(dev, plane);
881+ high_frame = pipe ? PIPEBFRAMEHIGH : PIPEAFRAMEHIGH;
882+ low_frame = pipe ? PIPEBFRAMEPIXEL : PIPEAFRAMEPIXEL;
883+
884+ if (!i915_pipe_enabled(dev, pipe)) {
885+ DRM_ERROR("trying to get vblank count for disabled pipe %d\n", pipe);
886+ return 0;
887+ }
888+
889+ /*
890+ * High & low register fields aren't synchronized, so make sure
891+ * we get a low value that's stable across two reads of the high
892+ * register.
893+ */
894+ do {
895+ high1 = ((I915_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >>
896+ PIPE_FRAME_HIGH_SHIFT);
897+ low = ((I915_READ(low_frame) & PIPE_FRAME_LOW_MASK) >>
898+ PIPE_FRAME_LOW_SHIFT);
899+ high2 = ((I915_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >>
900+ PIPE_FRAME_HIGH_SHIFT);
901+ } while (high1 != high2);
902+
903+ count = (high1 << 8) | low;
904+
905+ return count;
906+}
907+
908 irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
909 {
910 struct drm_device *dev = (struct drm_device *) arg;
911 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
912- u32 pipea_stats, pipeb_stats;
913 u32 iir;
914-
915- pipea_stats = I915_READ(PIPEASTAT);
916- pipeb_stats = I915_READ(PIPEBSTAT);
917+ u32 pipea_stats, pipeb_stats;
918+ int vblank = 0;
919
920 if (dev->pdev->msi_enabled)
921 I915_WRITE(IMR, ~0);
922 iir = I915_READ(IIR);
923
924- DRM_DEBUG("iir=%08x\n", iir);
925-
926 if (iir == 0) {
927 if (dev->pdev->msi_enabled) {
928 I915_WRITE(IMR, dev_priv->irq_mask_reg);
929@@ -276,48 +369,56 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
930 return IRQ_NONE;
931 }
932
933- I915_WRITE(PIPEASTAT, pipea_stats);
934- I915_WRITE(PIPEBSTAT, pipeb_stats);
935-
936- I915_WRITE(IIR, iir);
937- if (dev->pdev->msi_enabled)
938- I915_WRITE(IMR, dev_priv->irq_mask_reg);
939- (void) I915_READ(IIR); /* Flush posted writes */
940-
941- dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
942-
943- if (iir & I915_USER_INTERRUPT)
944- DRM_WAKEUP(&dev_priv->irq_queue);
945-
946- if (iir & (I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT |
947- I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT)) {
948- int vblank_pipe = dev_priv->vblank_pipe;
949-
950- if ((vblank_pipe &
951- (DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B))
952- == (DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B)) {
953- if (iir & I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT)
954- atomic_inc(&dev->vbl_received);
955- if (iir & I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT)
956- atomic_inc(&dev->vbl_received2);
957- } else if (((iir & I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT) &&
958- (vblank_pipe & DRM_I915_VBLANK_PIPE_A)) ||
959- ((iir & I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT) &&
960- (vblank_pipe & DRM_I915_VBLANK_PIPE_B)))
961- atomic_inc(&dev->vbl_received);
962+ /*
963+ * Clear the PIPE(A|B)STAT regs before the IIR otherwise
964+ * we may get extra interrupts.
965+ */
966+ if (iir & I915_DISPLAY_PIPE_A_EVENT_INTERRUPT) {
967+ pipea_stats = I915_READ(PIPEASTAT);
968+ if (!(dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_A))
969+ pipea_stats &= ~(PIPE_START_VBLANK_INTERRUPT_ENABLE |
970+ PIPE_VBLANK_INTERRUPT_ENABLE);
971+ else if (pipea_stats & (PIPE_START_VBLANK_INTERRUPT_STATUS|
972+ PIPE_VBLANK_INTERRUPT_STATUS)) {
973+ vblank++;
974+ drm_handle_vblank(dev, i915_get_plane(dev, 0));
975+ }
976
977- DRM_WAKEUP(&dev->vbl_queue);
978- drm_vbl_send_signals(dev);
979+ I915_WRITE(PIPEASTAT, pipea_stats);
980+ }
981+ if (iir & I915_DISPLAY_PIPE_B_EVENT_INTERRUPT) {
982+ pipeb_stats = I915_READ(PIPEBSTAT);
983+ /* Ack the event */
984+ I915_WRITE(PIPEBSTAT, pipeb_stats);
985+
986+ /* The vblank interrupt gets enabled even if we didn't ask for
987+ it, so make sure it's shut down again */
988+ if (!(dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_B))
989+ pipeb_stats &= ~(PIPE_START_VBLANK_INTERRUPT_ENABLE |
990+ PIPE_VBLANK_INTERRUPT_ENABLE);
991+ else if (pipeb_stats & (PIPE_START_VBLANK_INTERRUPT_STATUS|
992+ PIPE_VBLANK_INTERRUPT_STATUS)) {
993+ vblank++;
994+ drm_handle_vblank(dev, i915_get_plane(dev, 1));
995+ }
996
997- if (dev_priv->swaps_pending > 0)
998- drm_locked_tasklet(dev, i915_vblank_tasklet);
999+ if (pipeb_stats & I915_LEGACY_BLC_EVENT_STATUS)
1000+ opregion_asle_intr(dev);
1001+ I915_WRITE(PIPEBSTAT, pipeb_stats);
1002 }
1003
1004 if (iir & I915_ASLE_INTERRUPT)
1005 opregion_asle_intr(dev);
1006
1007- if (iir & I915_DISPLAY_PIPE_B_EVENT_INTERRUPT)
1008- opregion_asle_intr(dev);
1009+ dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
1010+
1011+ if (dev->pdev->msi_enabled)
1012+ I915_WRITE(IMR, dev_priv->irq_mask_reg);
1013+ I915_WRITE(IIR, iir);
1014+ (void) I915_READ(IIR);
1015+
1016+ if (vblank && dev_priv->swaps_pending > 0)
1017+ drm_locked_tasklet(dev, i915_vblank_tasklet);
1018
1019 return IRQ_HANDLED;
1020 }
1021@@ -358,7 +459,7 @@ static void i915_user_irq_get(struct drm_device *dev)
1022 spin_unlock(&dev_priv->user_irq_lock);
1023 }
1024
1025-static void i915_user_irq_put(struct drm_device *dev)
1026+void i915_user_irq_put(struct drm_device *dev)
1027 {
1028 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
1029
1030@@ -395,41 +496,10 @@ static int i915_wait_irq(struct drm_device * dev, int irq_nr)
1031 }
1032
1033 dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
1034- return ret;
1035-}
1036-
1037-static int i915_driver_vblank_do_wait(struct drm_device *dev, unsigned int *sequence,
1038- atomic_t *counter)
1039-{
1040- drm_i915_private_t *dev_priv = dev->dev_private;
1041- unsigned int cur_vblank;
1042- int ret = 0;
1043-
1044- if (!dev_priv) {
1045- DRM_ERROR("called with no initialization\n");
1046- return -EINVAL;
1047- }
1048-
1049- DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
1050- (((cur_vblank = atomic_read(counter))
1051- - *sequence) <= (1<<23)));
1052-
1053- *sequence = cur_vblank;
1054
1055 return ret;
1056 }
1057
1058-
1059-int i915_driver_vblank_wait(struct drm_device *dev, unsigned int *sequence)
1060-{
1061- return i915_driver_vblank_do_wait(dev, sequence, &dev->vbl_received);
1062-}
1063-
1064-int i915_driver_vblank_wait2(struct drm_device *dev, unsigned int *sequence)
1065-{
1066- return i915_driver_vblank_do_wait(dev, sequence, &dev->vbl_received2);
1067-}
1068-
1069 /* Needs the lock as it touches the ring.
1070 */
1071 int i915_irq_emit(struct drm_device *dev, void *data,
1072@@ -472,40 +542,88 @@ int i915_irq_wait(struct drm_device *dev, void *data,
1073 return i915_wait_irq(dev, irqwait->irq_seq);
1074 }
1075
1076+int i915_enable_vblank(struct drm_device *dev, int plane)
1077+{
1078+ drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
1079+ int pipe = i915_get_pipe(dev, plane);
1080+ u32 pipestat_reg = 0;
1081+ u32 pipestat;
1082+
1083+ switch (pipe) {
1084+ case 0:
1085+ pipestat_reg = PIPEASTAT;
1086+ i915_enable_irq(dev_priv, I915_DISPLAY_PIPE_A_EVENT_INTERRUPT);
1087+ break;
1088+ case 1:
1089+ pipestat_reg = PIPEBSTAT;
1090+ i915_enable_irq(dev_priv, I915_DISPLAY_PIPE_B_EVENT_INTERRUPT);
1091+ break;
1092+ default:
1093+ DRM_ERROR("tried to enable vblank on non-existent pipe %d\n",
1094+ pipe);
1095+ break;
1096+ }
1097+
1098+ if (pipestat_reg) {
1099+ pipestat = I915_READ(pipestat_reg);
1100+ if (IS_I965G(dev))
1101+ pipestat |= PIPE_START_VBLANK_INTERRUPT_ENABLE;
1102+ else
1103+ pipestat |= PIPE_VBLANK_INTERRUPT_ENABLE;
1104+ /* Clear any stale interrupt status */
1105+ pipestat |= (PIPE_START_VBLANK_INTERRUPT_STATUS |
1106+ PIPE_VBLANK_INTERRUPT_STATUS);
1107+ I915_WRITE(pipestat_reg, pipestat);
1108+ }
1109+
1110+ return 0;
1111+}
1112+
1113+void i915_disable_vblank(struct drm_device *dev, int plane)
1114+{
1115+ drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
1116+ int pipe = i915_get_pipe(dev, plane);
1117+ u32 pipestat_reg = 0;
1118+ u32 pipestat;
1119+
1120+ switch (pipe) {
1121+ case 0:
1122+ pipestat_reg = PIPEASTAT;
1123+ i915_disable_irq(dev_priv, I915_DISPLAY_PIPE_A_EVENT_INTERRUPT);
1124+ break;
1125+ case 1:
1126+ pipestat_reg = PIPEBSTAT;
1127+ i915_disable_irq(dev_priv, I915_DISPLAY_PIPE_B_EVENT_INTERRUPT);
1128+ break;
1129+ default:
1130+ DRM_ERROR("tried to disable vblank on non-existent pipe %d\n",
1131+ pipe);
1132+ break;
1133+ }
1134+
1135+ if (pipestat_reg) {
1136+ pipestat = I915_READ(pipestat_reg);
1137+ pipestat &= ~(PIPE_START_VBLANK_INTERRUPT_ENABLE |
1138+ PIPE_VBLANK_INTERRUPT_ENABLE);
1139+ /* Clear any stale interrupt status */
1140+ pipestat |= (PIPE_START_VBLANK_INTERRUPT_STATUS |
1141+ PIPE_VBLANK_INTERRUPT_STATUS);
1142+ I915_WRITE(pipestat_reg, pipestat);
1143+ }
1144+}
1145+
1146 /* Set the vblank monitor pipe
1147 */
1148 int i915_vblank_pipe_set(struct drm_device *dev, void *data,
1149 struct drm_file *file_priv)
1150 {
1151 drm_i915_private_t *dev_priv = dev->dev_private;
1152- drm_i915_vblank_pipe_t *pipe = data;
1153- u32 enable_mask = 0, disable_mask = 0;
1154
1155 if (!dev_priv) {
1156 DRM_ERROR("called with no initialization\n");
1157 return -EINVAL;
1158 }
1159
1160- if (pipe->pipe & ~(DRM_I915_VBLANK_PIPE_A|DRM_I915_VBLANK_PIPE_B)) {
1161- DRM_ERROR("called with invalid pipe 0x%x\n", pipe->pipe);
1162- return -EINVAL;
1163- }
1164-
1165- if (pipe->pipe & DRM_I915_VBLANK_PIPE_A)
1166- enable_mask |= I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT;
1167- else
1168- disable_mask |= I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT;
1169-
1170- if (pipe->pipe & DRM_I915_VBLANK_PIPE_B)
1171- enable_mask |= I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
1172- else
1173- disable_mask |= I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
1174-
1175- i915_enable_irq(dev_priv, enable_mask);
1176- i915_disable_irq(dev_priv, disable_mask);
1177-
1178- dev_priv->vblank_pipe = pipe->pipe;
1179-
1180 return 0;
1181 }
1182
1183@@ -514,19 +632,13 @@ int i915_vblank_pipe_get(struct drm_device *dev, void *data,
1184 {
1185 drm_i915_private_t *dev_priv = dev->dev_private;
1186 drm_i915_vblank_pipe_t *pipe = data;
1187- u16 flag;
1188
1189 if (!dev_priv) {
1190 DRM_ERROR("called with no initialization\n");
1191 return -EINVAL;
1192 }
1193
1194- flag = I915_READ(IMR);
1195- pipe->pipe = 0;
1196- if (flag & I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT)
1197- pipe->pipe |= DRM_I915_VBLANK_PIPE_A;
1198- if (flag & I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT)
1199- pipe->pipe |= DRM_I915_VBLANK_PIPE_B;
1200+ pipe->pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B;
1201
1202 return 0;
1203 }
1204@@ -540,9 +652,10 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
1205 drm_i915_private_t *dev_priv = dev->dev_private;
1206 drm_i915_vblank_swap_t *swap = data;
1207 drm_i915_vbl_swap_t *vbl_swap;
1208- unsigned int pipe, seqtype, curseq;
1209+ unsigned int pipe, seqtype, curseq, plane;
1210 unsigned long irqflags;
1211 struct list_head *list;
1212+ int ret;
1213
1214 if (!dev_priv) {
1215 DRM_ERROR("%s called with no initialization\n", __func__);
1216@@ -560,7 +673,8 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
1217 return -EINVAL;
1218 }
1219
1220- pipe = (swap->seqtype & _DRM_VBLANK_SECONDARY) ? 1 : 0;
1221+ plane = (swap->seqtype & _DRM_VBLANK_SECONDARY) ? 1 : 0;
1222+ pipe = i915_get_pipe(dev, plane);
1223
1224 seqtype = swap->seqtype & (_DRM_VBLANK_RELATIVE | _DRM_VBLANK_ABSOLUTE);
1225
1226@@ -579,7 +693,14 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
1227
1228 spin_unlock_irqrestore(&dev->drw_lock, irqflags);
1229
1230- curseq = atomic_read(pipe ? &dev->vbl_received2 : &dev->vbl_received);
1231+ /*
1232+ * We take the ref here and put it when the swap actually completes
1233+ * in the tasklet.
1234+ */
1235+ ret = drm_vblank_get(dev, pipe);
1236+ if (ret)
1237+ return ret;
1238+ curseq = drm_vblank_count(dev, pipe);
1239
1240 if (seqtype == _DRM_VBLANK_RELATIVE)
1241 swap->sequence += curseq;
1242@@ -589,6 +710,7 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
1243 swap->sequence = curseq + 1;
1244 } else {
1245 DRM_DEBUG("Missed target sequence\n");
1246+ drm_vblank_put(dev, pipe);
1247 return -EINVAL;
1248 }
1249 }
1250@@ -599,7 +721,7 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
1251 vbl_swap = list_entry(list, drm_i915_vbl_swap_t, head);
1252
1253 if (vbl_swap->drw_id == swap->drawable &&
1254- vbl_swap->pipe == pipe &&
1255+ vbl_swap->plane == plane &&
1256 vbl_swap->sequence == swap->sequence) {
1257 spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags);
1258 DRM_DEBUG("Already scheduled\n");
1259@@ -611,6 +733,7 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
1260
1261 if (dev_priv->swaps_pending >= 100) {
1262 DRM_DEBUG("Too many swaps queued\n");
1263+ drm_vblank_put(dev, pipe);
1264 return -EBUSY;
1265 }
1266
1267@@ -618,13 +741,14 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
1268
1269 if (!vbl_swap) {
1270 DRM_ERROR("Failed to allocate memory to queue swap\n");
1271+ drm_vblank_put(dev, pipe);
1272 return -ENOMEM;
1273 }
1274
1275 DRM_DEBUG("\n");
1276
1277 vbl_swap->drw_id = swap->drawable;
1278- vbl_swap->pipe = pipe;
1279+ vbl_swap->plane = plane;
1280 vbl_swap->sequence = swap->sequence;
1281
1282 spin_lock_irqsave(&dev_priv->swaps_lock, irqflags);
1283@@ -643,28 +767,32 @@ void i915_driver_irq_preinstall(struct drm_device * dev)
1284 {
1285 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
1286
1287- I915_WRITE(HWSTAM, 0xfffe);
1288- I915_WRITE(IMR, 0x0);
1289+ I915_WRITE(HWSTAM, 0xeffe);
1290+ I915_WRITE(IMR, 0xffffffff);
1291 I915_WRITE(IER, 0x0);
1292 }
1293
1294-void i915_driver_irq_postinstall(struct drm_device * dev)
1295+int i915_driver_irq_postinstall(struct drm_device *dev)
1296 {
1297 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
1298+ int ret, num_pipes = 2;
1299
1300 spin_lock_init(&dev_priv->swaps_lock);
1301 INIT_LIST_HEAD(&dev_priv->vbl_swaps.head);
1302 dev_priv->swaps_pending = 0;
1303
1304- if (!dev_priv->vblank_pipe)
1305- dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A;
1306-
1307 /* Set initial unmasked IRQs to just the selected vblank pipes. */
1308 dev_priv->irq_mask_reg = ~0;
1309- if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_A)
1310- dev_priv->irq_mask_reg &= ~I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT;
1311- if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_B)
1312- dev_priv->irq_mask_reg &= ~I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
1313+
1314+ ret = drm_vblank_init(dev, num_pipes);
1315+ if (ret)
1316+ return ret;
1317+
1318+ dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B;
1319+ dev_priv->irq_mask_reg &= ~I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT;
1320+ dev_priv->irq_mask_reg &= ~I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT;
1321+
1322+ dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */
1323
1324 dev_priv->irq_mask_reg &= I915_INTERRUPT_ENABLE_MASK;
1325
1326@@ -673,22 +801,29 @@ void i915_driver_irq_postinstall(struct drm_device * dev)
1327 (void) I915_READ(IER);
1328
1329 opregion_enable_asle(dev);
1330-
1331 DRM_INIT_WAITQUEUE(&dev_priv->irq_queue);
1332+
1333+ return 0;
1334 }
1335
1336 void i915_driver_irq_uninstall(struct drm_device * dev)
1337 {
1338 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
1339- u16 temp;
1340+ u32 temp;
1341
1342 if (!dev_priv)
1343 return;
1344
1345- I915_WRITE(HWSTAM, 0xffff);
1346- I915_WRITE(IMR, 0xffff);
1347+ dev_priv->vblank_pipe = 0;
1348+
1349+ I915_WRITE(HWSTAM, 0xffffffff);
1350+ I915_WRITE(IMR, 0xffffffff);
1351 I915_WRITE(IER, 0x0);
1352
1353+ temp = I915_READ(PIPEASTAT);
1354+ I915_WRITE(PIPEASTAT, temp);
1355+ temp = I915_READ(PIPEBSTAT);
1356+ I915_WRITE(PIPEBSTAT, temp);
1357 temp = I915_READ(IIR);
1358 I915_WRITE(IIR, temp);
1359 }
1360diff --git a/include/drm/drm.h b/include/drm/drm.h
1361index 0864c69..15e5503 100644
1362--- a/include/drm/drm.h
1363+++ b/include/drm/drm.h
1364@@ -454,6 +454,7 @@ struct drm_irq_busid {
1365 enum drm_vblank_seq_type {
1366 _DRM_VBLANK_ABSOLUTE = 0x0, /**< Wait for specific vblank sequence number */
1367 _DRM_VBLANK_RELATIVE = 0x1, /**< Wait for given number of vblanks */
1368+ _DRM_VBLANK_FLIP = 0x8000000, /**< Scheduled buffer swap should flip */
1369 _DRM_VBLANK_NEXTONMISS = 0x10000000, /**< If missed, wait for next vblank */
1370 _DRM_VBLANK_SECONDARY = 0x20000000, /**< Secondary display controller */
1371 _DRM_VBLANK_SIGNAL = 0x40000000 /**< Send signal instead of blocking */
1372@@ -486,6 +487,19 @@ union drm_wait_vblank {
1373 struct drm_wait_vblank_reply reply;
1374 };
1375
1376+#define _DRM_PRE_MODESET 1
1377+#define _DRM_POST_MODESET 2
1378+
1379+/**
1380+ * DRM_IOCTL_MODESET_CTL ioctl argument type
1381+ *
1382+ * \sa drmModesetCtl().
1383+ */
1384+struct drm_modeset_ctl {
1385+ uint32_t crtc;
1386+ uint32_t cmd;
1387+};
1388+
1389 /**
1390 * DRM_IOCTL_AGP_ENABLE ioctl argument type.
1391 *
1392@@ -570,6 +584,7 @@ struct drm_set_version {
1393 #define DRM_IOCTL_GET_CLIENT DRM_IOWR(0x05, struct drm_client)
1394 #define DRM_IOCTL_GET_STATS DRM_IOR( 0x06, struct drm_stats)
1395 #define DRM_IOCTL_SET_VERSION DRM_IOWR(0x07, struct drm_set_version)
1396+#define DRM_IOCTL_MODESET_CTL DRM_IOW(0x08, struct drm_modeset_ctl)
1397
1398 #define DRM_IOCTL_SET_UNIQUE DRM_IOW( 0x10, struct drm_unique)
1399 #define DRM_IOCTL_AUTH_MAGIC DRM_IOW( 0x11, struct drm_auth)
1400diff --git a/include/drm/drmP.h b/include/drm/drmP.h
1401index 1c1b13e..e79ce07 100644
1402--- a/include/drm/drmP.h
1403+++ b/include/drm/drmP.h
1404@@ -580,11 +580,54 @@ struct drm_driver {
1405 int (*kernel_context_switch) (struct drm_device *dev, int old,
1406 int new);
1407 void (*kernel_context_switch_unlock) (struct drm_device *dev);
1408- int (*vblank_wait) (struct drm_device *dev, unsigned int *sequence);
1409- int (*vblank_wait2) (struct drm_device *dev, unsigned int *sequence);
1410 int (*dri_library_name) (struct drm_device *dev, char *buf);
1411
1412 /**
1413+ * get_vblank_counter - get raw hardware vblank counter
1414+ * @dev: DRM device
1415+ * @crtc: counter to fetch
1416+ *
1417+ * Driver callback for fetching a raw hardware vblank counter
1418+ * for @crtc. If a device doesn't have a hardware counter, the
1419+ * driver can simply return the value of drm_vblank_count and
1420+ * make the enable_vblank() and disable_vblank() hooks into no-ops,
1421+ * leaving interrupts enabled at all times.
1422+ *
1423+ * Wraparound handling and loss of events due to modesetting is dealt
1424+ * with in the DRM core code.
1425+ *
1426+ * RETURNS
1427+ * Raw vblank counter value.
1428+ */
1429+ u32 (*get_vblank_counter) (struct drm_device *dev, int crtc);
1430+
1431+ /**
1432+ * enable_vblank - enable vblank interrupt events
1433+ * @dev: DRM device
1434+ * @crtc: which irq to enable
1435+ *
1436+ * Enable vblank interrupts for @crtc. If the device doesn't have
1437+ * a hardware vblank counter, this routine should be a no-op, since
1438+ * interrupts will have to stay on to keep the count accurate.
1439+ *
1440+ * RETURNS
1441+ * Zero on success, appropriate errno if the given @crtc's vblank
1442+ * interrupt cannot be enabled.
1443+ */
1444+ int (*enable_vblank) (struct drm_device *dev, int crtc);
1445+
1446+ /**
1447+ * disable_vblank - disable vblank interrupt events
1448+ * @dev: DRM device
1449+ * @crtc: which irq to enable
1450+ *
1451+ * Disable vblank interrupts for @crtc. If the device doesn't have
1452+ * a hardware vblank counter, this routine should be a no-op, since
1453+ * interrupts will have to stay on to keep the count accurate.
1454+ */
1455+ void (*disable_vblank) (struct drm_device *dev, int crtc);
1456+
1457+ /**
1458 * Called by \c drm_device_is_agp. Typically used to determine if a
1459 * card is really attached to AGP or not.
1460 *
1461@@ -601,7 +644,7 @@ struct drm_driver {
1462
1463 irqreturn_t(*irq_handler) (DRM_IRQ_ARGS);
1464 void (*irq_preinstall) (struct drm_device *dev);
1465- void (*irq_postinstall) (struct drm_device *dev);
1466+ int (*irq_postinstall) (struct drm_device *dev);
1467 void (*irq_uninstall) (struct drm_device *dev);
1468 void (*reclaim_buffers) (struct drm_device *dev,
1469 struct drm_file * file_priv);
1470@@ -730,13 +773,28 @@ struct drm_device {
1471 /** \name VBLANK IRQ support */
1472 /*@{ */
1473
1474- wait_queue_head_t vbl_queue; /**< VBLANK wait queue */
1475- atomic_t vbl_received;
1476- atomic_t vbl_received2; /**< number of secondary VBLANK interrupts */
1477+ /*
1478+ * At load time, disabling the vblank interrupt won't be allowed since
1479+ * old clients may not call the modeset ioctl and therefore misbehave.
1480+ * Once the modeset ioctl *has* been called though, we can safely
1481+ * disable them when unused.
1482+ */
1483+ int vblank_disable_allowed;
1484+
1485+ wait_queue_head_t *vbl_queue; /**< VBLANK wait queue */
1486+ atomic_t *_vblank_count; /**< number of VBLANK interrupts (driver must alloc the right number of counters) */
1487 spinlock_t vbl_lock;
1488- struct list_head vbl_sigs; /**< signal list to send on VBLANK */
1489- struct list_head vbl_sigs2; /**< signals to send on secondary VBLANK */
1490- unsigned int vbl_pending;
1491+ struct list_head *vbl_sigs; /**< signal list to send on VBLANK */
1492+ atomic_t vbl_signal_pending; /* number of signals pending on all crtcs*/
1493+ atomic_t *vblank_refcount; /* number of users of vblank interruptsper crtc */
1494+ u32 *last_vblank; /* protected by dev->vbl_lock, used */
1495+ /* for wraparound handling */
1496+ int *vblank_enabled; /* so we don't call enable more than
1497+ once per disable */
1498+ int *vblank_inmodeset; /* Display driver is setting mode */
1499+ struct timer_list vblank_disable_timer;
1500+
1501+ u32 max_vblank_count; /**< size of vblank counter register */
1502 spinlock_t tasklet_lock; /**< For drm_locked_tasklet */
1503 void (*locked_tasklet_func)(struct drm_device *dev);
1504
1505@@ -757,6 +815,7 @@ struct drm_device {
1506 struct pci_controller *hose;
1507 #endif
1508 struct drm_sg_mem *sg; /**< Scatter gather memory */
1509+ int num_crtcs; /**< Number of CRTCs on this device */
1510 void *dev_private; /**< device private data */
1511 struct drm_sigdata sigdata; /**< For block_all_signals */
1512 sigset_t sigmask;
1513@@ -990,10 +1049,19 @@ extern void drm_driver_irq_preinstall(struct drm_device *dev);
1514 extern void drm_driver_irq_postinstall(struct drm_device *dev);
1515 extern void drm_driver_irq_uninstall(struct drm_device *dev);
1516
1517+extern int drm_vblank_init(struct drm_device *dev, int num_crtcs);
1518 extern int drm_wait_vblank(struct drm_device *dev, void *data,
1519- struct drm_file *file_priv);
1520+ struct drm_file *filp);
1521 extern int drm_vblank_wait(struct drm_device *dev, unsigned int *vbl_seq);
1522-extern void drm_vbl_send_signals(struct drm_device *dev);
1523+extern void drm_locked_tasklet(struct drm_device *dev,
1524+ void(*func)(struct drm_device *));
1525+extern u32 drm_vblank_count(struct drm_device *dev, int crtc);
1526+extern void drm_handle_vblank(struct drm_device *dev, int crtc);
1527+extern int drm_vblank_get(struct drm_device *dev, int crtc);
1528+extern void drm_vblank_put(struct drm_device *dev, int crtc);
1529+/* Modesetting support */
1530+extern int drm_modeset_ctl(struct drm_device *dev, void *data,
1531+ struct drm_file *file_priv);
1532 extern void drm_locked_tasklet(struct drm_device *dev, void(*func)(struct drm_device*));
1533
1534 /* AGP/GART support (drm_agpsupport.h) */
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27/0012-Export-shmem_file_setup-for-DRM-GEM.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27/0012-Export-shmem_file_setup-for-DRM-GEM.patch
new file mode 100644
index 0000000000..642d89ba76
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27/0012-Export-shmem_file_setup-for-DRM-GEM.patch
@@ -0,0 +1,25 @@
1commit 48e13db26a25ebaf61f1fc28f612d6b35ddf1965
2Author: Keith Packard <keithp@keithp.com>
3Date: Fri Jun 20 00:08:06 2008 -0700
4
5 Export shmem_file_setup for DRM-GEM
6
7 GEM needs to create shmem files to back buffer objects. Though currently
8 creation of files for objects could have been driven from userland, the
9 modesetting work will require allocation of buffer objects before userland
10 is running, for boot-time message display.
11
12 Signed-off-by: Eric Anholt <eric@anholt.net>
13
14diff --git a/mm/shmem.c b/mm/shmem.c
15index 04fb4f1..515909d 100644
16--- a/mm/shmem.c
17+++ b/mm/shmem.c
18@@ -2582,6 +2582,7 @@ put_memory:
19 shmem_unacct_size(flags, size);
20 return ERR_PTR(error);
21 }
22+EXPORT_SYMBOL(shmem_file_setup);
23
24 /**
25 * shmem_zero_setup - setup a shared anonymous mapping
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27/0013-Export-kmap_atomic_pfn-for-DRM-GEM.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27/0013-Export-kmap_atomic_pfn-for-DRM-GEM.patch
new file mode 100644
index 0000000000..cc90d46262
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27/0013-Export-kmap_atomic_pfn-for-DRM-GEM.patch
@@ -0,0 +1,24 @@
1commit 25eaa97fc74b225e13cf11ed8d770192ddc9355d
2Author: Eric Anholt <eric@anholt.net>
3Date: Thu Aug 21 12:53:33 2008 -0700
4
5 Export kmap_atomic_pfn for DRM-GEM.
6
7 The driver would like to map IO space directly for copying data in when
8 appropriate, to avoid CPU cache flushing for streaming writes.
9 kmap_atomic_pfn lets us avoid IPIs associated with ioremap for this process.
10
11 Signed-off-by: Eric Anholt <eric@anholt.net>
12
13diff --git a/arch/x86/mm/highmem_32.c b/arch/x86/mm/highmem_32.c
14index 165c871..d52e91d 100644
15--- a/arch/x86/mm/highmem_32.c
16+++ b/arch/x86/mm/highmem_32.c
17@@ -137,6 +137,7 @@ void *kmap_atomic_pfn(unsigned long pfn, enum km_type type)
18
19 return (void*) vaddr;
20 }
21+EXPORT_SYMBOL(kmap_atomic_pfn);
22
23 struct page *kmap_atomic_to_page(void *ptr)
24 {
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27/0014-drm-Add-GEM-graphics-execution-manager-to-i915.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27/0014-drm-Add-GEM-graphics-execution-manager-to-i915.patch
new file mode 100644
index 0000000000..95cca5d0c6
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27/0014-drm-Add-GEM-graphics-execution-manager-to-i915.patch
@@ -0,0 +1,5483 @@
1commit c97398223c6a505fac2c783a624dc80e0aa5d5d0
2Author: Eric Anholt <eric@anholt.net>
3Date: Wed Jul 30 12:06:12 2008 -0700
4
5 drm: Add GEM ("graphics execution manager") to i915 driver.
6
7 GEM allows the creation of persistent buffer objects accessible by the
8 graphics device through new ioctls for managing execution of commands on the
9 device. The userland API is almost entirely driver-specific to ensure that
10 any driver building on this model can easily map the interface to individual
11 driver requirements.
12
13 GEM is used by the 2d driver for managing its internal state allocations and
14 will be used for pixmap storage to reduce memory consumption and enable
15 zero-copy GLX_EXT_texture_from_pixmap, and in the 3d driver is used to enable
16 GL_EXT_framebuffer_object and GL_ARB_pixel_buffer_object.
17
18 Signed-off-by: Eric Anholt <eric@anholt.net>
19
20diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
21index e9f9a97..74da994 100644
22--- a/drivers/gpu/drm/Makefile
23+++ b/drivers/gpu/drm/Makefile
24@@ -4,8 +4,9 @@
25
26 ccflags-y := -Iinclude/drm
27
28-drm-y := drm_auth.o drm_bufs.o drm_context.o drm_dma.o drm_drawable.o \
29- drm_drv.o drm_fops.o drm_ioctl.o drm_irq.o \
30+drm-y := drm_auth.o drm_bufs.o drm_cache.o \
31+ drm_context.o drm_dma.o drm_drawable.o \
32+ drm_drv.o drm_fops.o drm_gem.o drm_ioctl.o drm_irq.o \
33 drm_lock.o drm_memory.o drm_proc.o drm_stub.o drm_vm.o \
34 drm_agpsupport.o drm_scatter.o ati_pcigart.o drm_pci.o \
35 drm_sysfs.o drm_hashtab.o drm_sman.o drm_mm.o
36diff --git a/drivers/gpu/drm/drm_agpsupport.c b/drivers/gpu/drm/drm_agpsupport.c
37index aefa5ac..2639be2 100644
38--- a/drivers/gpu/drm/drm_agpsupport.c
39+++ b/drivers/gpu/drm/drm_agpsupport.c
40@@ -33,6 +33,7 @@
41
42 #include "drmP.h"
43 #include <linux/module.h>
44+#include <asm/agp.h>
45
46 #if __OS_HAS_AGP
47
48@@ -452,4 +453,52 @@ int drm_agp_unbind_memory(DRM_AGP_MEM * handle)
49 return agp_unbind_memory(handle);
50 }
51
52-#endif /* __OS_HAS_AGP */
53+/**
54+ * Binds a collection of pages into AGP memory at the given offset, returning
55+ * the AGP memory structure containing them.
56+ *
57+ * No reference is held on the pages during this time -- it is up to the
58+ * caller to handle that.
59+ */
60+DRM_AGP_MEM *
61+drm_agp_bind_pages(struct drm_device *dev,
62+ struct page **pages,
63+ unsigned long num_pages,
64+ uint32_t gtt_offset)
65+{
66+ DRM_AGP_MEM *mem;
67+ int ret, i;
68+
69+ DRM_DEBUG("\n");
70+
71+ mem = drm_agp_allocate_memory(dev->agp->bridge, num_pages,
72+ AGP_USER_MEMORY);
73+ if (mem == NULL) {
74+ DRM_ERROR("Failed to allocate memory for %ld pages\n",
75+ num_pages);
76+ return NULL;
77+ }
78+
79+ for (i = 0; i < num_pages; i++)
80+ mem->memory[i] = phys_to_gart(page_to_phys(pages[i]));
81+ mem->page_count = num_pages;
82+
83+ mem->is_flushed = true;
84+ ret = drm_agp_bind_memory(mem, gtt_offset / PAGE_SIZE);
85+ if (ret != 0) {
86+ DRM_ERROR("Failed to bind AGP memory: %d\n", ret);
87+ agp_free_memory(mem);
88+ return NULL;
89+ }
90+
91+ return mem;
92+}
93+EXPORT_SYMBOL(drm_agp_bind_pages);
94+
95+void drm_agp_chipset_flush(struct drm_device *dev)
96+{
97+ agp_flush_chipset(dev->agp->bridge);
98+}
99+EXPORT_SYMBOL(drm_agp_chipset_flush);
100+
101+#endif /* __OS_HAS_AGP */
102diff --git a/drivers/gpu/drm/drm_cache.c b/drivers/gpu/drm/drm_cache.c
103new file mode 100644
104index 0000000..9475f7d
105--- /dev/null
106+++ b/drivers/gpu/drm/drm_cache.c
107@@ -0,0 +1,76 @@
108+/**************************************************************************
109+ *
110+ * Copyright (c) 2006-2007 Tungsten Graphics, Inc., Cedar Park, TX., USA
111+ * All Rights Reserved.
112+ *
113+ * Permission is hereby granted, free of charge, to any person obtaining a
114+ * copy of this software and associated documentation files (the
115+ * "Software"), to deal in the Software without restriction, including
116+ * without limitation the rights to use, copy, modify, merge, publish,
117+ * distribute, sub license, and/or sell copies of the Software, and to
118+ * permit persons to whom the Software is furnished to do so, subject to
119+ * the following conditions:
120+ *
121+ * The above copyright notice and this permission notice (including the
122+ * next paragraph) shall be included in all copies or substantial portions
123+ * of the Software.
124+ *
125+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
126+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
127+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
128+ * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
129+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
130+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
131+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
132+ *
133+ **************************************************************************/
134+/*
135+ * Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com>
136+ */
137+
138+#include "drmP.h"
139+
140+#if defined(CONFIG_X86)
141+static void
142+drm_clflush_page(struct page *page)
143+{
144+ uint8_t *page_virtual;
145+ unsigned int i;
146+
147+ if (unlikely(page == NULL))
148+ return;
149+
150+ page_virtual = kmap_atomic(page, KM_USER0);
151+ for (i = 0; i < PAGE_SIZE; i += boot_cpu_data.x86_clflush_size)
152+ clflush(page_virtual + i);
153+ kunmap_atomic(page_virtual, KM_USER0);
154+}
155+#endif
156+
157+static void
158+drm_clflush_ipi_handler(void *null)
159+{
160+ wbinvd();
161+}
162+
163+void
164+drm_clflush_pages(struct page *pages[], unsigned long num_pages)
165+{
166+
167+#if defined(CONFIG_X86)
168+ if (cpu_has_clflush) {
169+ unsigned long i;
170+
171+ mb();
172+ for (i = 0; i < num_pages; ++i)
173+ drm_clflush_page(*pages++);
174+ mb();
175+
176+ return;
177+ }
178+#endif
179+
180+ if (on_each_cpu(drm_clflush_ipi_handler, NULL, 1) != 0)
181+ DRM_ERROR("Timed out waiting for cache flush.\n");
182+}
183+EXPORT_SYMBOL(drm_clflush_pages);
184diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
185index fb45fe7..96f416a 100644
186--- a/drivers/gpu/drm/drm_drv.c
187+++ b/drivers/gpu/drm/drm_drv.c
188@@ -119,6 +119,10 @@ static struct drm_ioctl_desc drm_ioctls[] = {
189 DRM_IOCTL_DEF(DRM_IOCTL_MODESET_CTL, drm_modeset_ctl, 0),
190
191 DRM_IOCTL_DEF(DRM_IOCTL_UPDATE_DRAW, drm_update_drawable_info, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
192+
193+ DRM_IOCTL_DEF(DRM_IOCTL_GEM_CLOSE, drm_gem_close_ioctl, 0),
194+ DRM_IOCTL_DEF(DRM_IOCTL_GEM_FLINK, drm_gem_flink_ioctl, DRM_AUTH),
195+ DRM_IOCTL_DEF(DRM_IOCTL_GEM_OPEN, drm_gem_open_ioctl, DRM_AUTH),
196 };
197
198 #define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls )
199diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
200index dcf8b4d..0d46627 100644
201--- a/drivers/gpu/drm/drm_fops.c
202+++ b/drivers/gpu/drm/drm_fops.c
203@@ -256,6 +256,9 @@ static int drm_open_helper(struct inode *inode, struct file *filp,
204
205 INIT_LIST_HEAD(&priv->lhead);
206
207+ if (dev->driver->driver_features & DRIVER_GEM)
208+ drm_gem_open(dev, priv);
209+
210 if (dev->driver->open) {
211 ret = dev->driver->open(dev, priv);
212 if (ret < 0)
213@@ -400,6 +403,9 @@ int drm_release(struct inode *inode, struct file *filp)
214 dev->driver->reclaim_buffers(dev, file_priv);
215 }
216
217+ if (dev->driver->driver_features & DRIVER_GEM)
218+ drm_gem_release(dev, file_priv);
219+
220 drm_fasync(-1, filp, 0);
221
222 mutex_lock(&dev->ctxlist_mutex);
223diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
224new file mode 100644
225index 0000000..434155b
226--- /dev/null
227+++ b/drivers/gpu/drm/drm_gem.c
228@@ -0,0 +1,420 @@
229+/*
230+ * Copyright © 2008 Intel Corporation
231+ *
232+ * Permission is hereby granted, free of charge, to any person obtaining a
233+ * copy of this software and associated documentation files (the "Software"),
234+ * to deal in the Software without restriction, including without limitation
235+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
236+ * and/or sell copies of the Software, and to permit persons to whom the
237+ * Software is furnished to do so, subject to the following conditions:
238+ *
239+ * The above copyright notice and this permission notice (including the next
240+ * paragraph) shall be included in all copies or substantial portions of the
241+ * Software.
242+ *
243+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
244+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
245+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
246+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
247+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
248+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
249+ * IN THE SOFTWARE.
250+ *
251+ * Authors:
252+ * Eric Anholt <eric@anholt.net>
253+ *
254+ */
255+
256+#include <linux/types.h>
257+#include <linux/slab.h>
258+#include <linux/mm.h>
259+#include <linux/uaccess.h>
260+#include <linux/fs.h>
261+#include <linux/file.h>
262+#include <linux/module.h>
263+#include <linux/mman.h>
264+#include <linux/pagemap.h>
265+#include "drmP.h"
266+
267+/** @file drm_gem.c
268+ *
269+ * This file provides some of the base ioctls and library routines for
270+ * the graphics memory manager implemented by each device driver.
271+ *
272+ * Because various devices have different requirements in terms of
273+ * synchronization and migration strategies, implementing that is left up to
274+ * the driver, and all that the general API provides should be generic --
275+ * allocating objects, reading/writing data with the cpu, freeing objects.
276+ * Even there, platform-dependent optimizations for reading/writing data with
277+ * the CPU mean we'll likely hook those out to driver-specific calls. However,
278+ * the DRI2 implementation wants to have at least allocate/mmap be generic.
279+ *
280+ * The goal was to have swap-backed object allocation managed through
281+ * struct file. However, file descriptors as handles to a struct file have
282+ * two major failings:
283+ * - Process limits prevent more than 1024 or so being used at a time by
284+ * default.
285+ * - Inability to allocate high fds will aggravate the X Server's select()
286+ * handling, and likely that of many GL client applications as well.
287+ *
288+ * This led to a plan of using our own integer IDs (called handles, following
289+ * DRM terminology) to mimic fds, and implement the fd syscalls we need as
290+ * ioctls. The objects themselves will still include the struct file so
291+ * that we can transition to fds if the required kernel infrastructure shows
292+ * up at a later date, and as our interface with shmfs for memory allocation.
293+ */
294+
295+/**
296+ * Initialize the GEM device fields
297+ */
298+
299+int
300+drm_gem_init(struct drm_device *dev)
301+{
302+ spin_lock_init(&dev->object_name_lock);
303+ idr_init(&dev->object_name_idr);
304+ atomic_set(&dev->object_count, 0);
305+ atomic_set(&dev->object_memory, 0);
306+ atomic_set(&dev->pin_count, 0);
307+ atomic_set(&dev->pin_memory, 0);
308+ atomic_set(&dev->gtt_count, 0);
309+ atomic_set(&dev->gtt_memory, 0);
310+ return 0;
311+}
312+
313+/**
314+ * Allocate a GEM object of the specified size with shmfs backing store
315+ */
316+struct drm_gem_object *
317+drm_gem_object_alloc(struct drm_device *dev, size_t size)
318+{
319+ struct drm_gem_object *obj;
320+
321+ BUG_ON((size & (PAGE_SIZE - 1)) != 0);
322+
323+ obj = kcalloc(1, sizeof(*obj), GFP_KERNEL);
324+
325+ obj->dev = dev;
326+ obj->filp = shmem_file_setup("drm mm object", size, 0);
327+ if (IS_ERR(obj->filp)) {
328+ kfree(obj);
329+ return NULL;
330+ }
331+
332+ kref_init(&obj->refcount);
333+ kref_init(&obj->handlecount);
334+ obj->size = size;
335+ if (dev->driver->gem_init_object != NULL &&
336+ dev->driver->gem_init_object(obj) != 0) {
337+ fput(obj->filp);
338+ kfree(obj);
339+ return NULL;
340+ }
341+ atomic_inc(&dev->object_count);
342+ atomic_add(obj->size, &dev->object_memory);
343+ return obj;
344+}
345+EXPORT_SYMBOL(drm_gem_object_alloc);
346+
347+/**
348+ * Removes the mapping from handle to filp for this object.
349+ */
350+static int
351+drm_gem_handle_delete(struct drm_file *filp, int handle)
352+{
353+ struct drm_device *dev;
354+ struct drm_gem_object *obj;
355+
356+ /* This is gross. The idr system doesn't let us try a delete and
357+ * return an error code. It just spews if you fail at deleting.
358+ * So, we have to grab a lock around finding the object and then
359+ * doing the delete on it and dropping the refcount, or the user
360+ * could race us to double-decrement the refcount and cause a
361+ * use-after-free later. Given the frequency of our handle lookups,
362+ * we may want to use ida for number allocation and a hash table
363+ * for the pointers, anyway.
364+ */
365+ spin_lock(&filp->table_lock);
366+
367+ /* Check if we currently have a reference on the object */
368+ obj = idr_find(&filp->object_idr, handle);
369+ if (obj == NULL) {
370+ spin_unlock(&filp->table_lock);
371+ return -EINVAL;
372+ }
373+ dev = obj->dev;
374+
375+ /* Release reference and decrement refcount. */
376+ idr_remove(&filp->object_idr, handle);
377+ spin_unlock(&filp->table_lock);
378+
379+ mutex_lock(&dev->struct_mutex);
380+ drm_gem_object_handle_unreference(obj);
381+ mutex_unlock(&dev->struct_mutex);
382+
383+ return 0;
384+}
385+
386+/**
387+ * Create a handle for this object. This adds a handle reference
388+ * to the object, which includes a regular reference count. Callers
389+ * will likely want to dereference the object afterwards.
390+ */
391+int
392+drm_gem_handle_create(struct drm_file *file_priv,
393+ struct drm_gem_object *obj,
394+ int *handlep)
395+{
396+ int ret;
397+
398+ /*
399+ * Get the user-visible handle using idr.
400+ */
401+again:
402+ /* ensure there is space available to allocate a handle */
403+ if (idr_pre_get(&file_priv->object_idr, GFP_KERNEL) == 0)
404+ return -ENOMEM;
405+
406+ /* do the allocation under our spinlock */
407+ spin_lock(&file_priv->table_lock);
408+ ret = idr_get_new_above(&file_priv->object_idr, obj, 1, handlep);
409+ spin_unlock(&file_priv->table_lock);
410+ if (ret == -EAGAIN)
411+ goto again;
412+
413+ if (ret != 0)
414+ return ret;
415+
416+ drm_gem_object_handle_reference(obj);
417+ return 0;
418+}
419+EXPORT_SYMBOL(drm_gem_handle_create);
420+
421+/** Returns a reference to the object named by the handle. */
422+struct drm_gem_object *
423+drm_gem_object_lookup(struct drm_device *dev, struct drm_file *filp,
424+ int handle)
425+{
426+ struct drm_gem_object *obj;
427+
428+ spin_lock(&filp->table_lock);
429+
430+ /* Check if we currently have a reference on the object */
431+ obj = idr_find(&filp->object_idr, handle);
432+ if (obj == NULL) {
433+ spin_unlock(&filp->table_lock);
434+ return NULL;
435+ }
436+
437+ drm_gem_object_reference(obj);
438+
439+ spin_unlock(&filp->table_lock);
440+
441+ return obj;
442+}
443+EXPORT_SYMBOL(drm_gem_object_lookup);
444+
445+/**
446+ * Releases the handle to an mm object.
447+ */
448+int
449+drm_gem_close_ioctl(struct drm_device *dev, void *data,
450+ struct drm_file *file_priv)
451+{
452+ struct drm_gem_close *args = data;
453+ int ret;
454+
455+ if (!(dev->driver->driver_features & DRIVER_GEM))
456+ return -ENODEV;
457+
458+ ret = drm_gem_handle_delete(file_priv, args->handle);
459+
460+ return ret;
461+}
462+
463+/**
464+ * Create a global name for an object, returning the name.
465+ *
466+ * Note that the name does not hold a reference; when the object
467+ * is freed, the name goes away.
468+ */
469+int
470+drm_gem_flink_ioctl(struct drm_device *dev, void *data,
471+ struct drm_file *file_priv)
472+{
473+ struct drm_gem_flink *args = data;
474+ struct drm_gem_object *obj;
475+ int ret;
476+
477+ if (!(dev->driver->driver_features & DRIVER_GEM))
478+ return -ENODEV;
479+
480+ obj = drm_gem_object_lookup(dev, file_priv, args->handle);
481+ if (obj == NULL)
482+ return -EINVAL;
483+
484+again:
485+ if (idr_pre_get(&dev->object_name_idr, GFP_KERNEL) == 0)
486+ return -ENOMEM;
487+
488+ spin_lock(&dev->object_name_lock);
489+ if (obj->name) {
490+ spin_unlock(&dev->object_name_lock);
491+ return -EEXIST;
492+ }
493+ ret = idr_get_new_above(&dev->object_name_idr, obj, 1,
494+ &obj->name);
495+ spin_unlock(&dev->object_name_lock);
496+ if (ret == -EAGAIN)
497+ goto again;
498+
499+ if (ret != 0) {
500+ mutex_lock(&dev->struct_mutex);
501+ drm_gem_object_unreference(obj);
502+ mutex_unlock(&dev->struct_mutex);
503+ return ret;
504+ }
505+
506+ /*
507+ * Leave the reference from the lookup around as the
508+ * name table now holds one
509+ */
510+ args->name = (uint64_t) obj->name;
511+
512+ return 0;
513+}
514+
515+/**
516+ * Open an object using the global name, returning a handle and the size.
517+ *
518+ * This handle (of course) holds a reference to the object, so the object
519+ * will not go away until the handle is deleted.
520+ */
521+int
522+drm_gem_open_ioctl(struct drm_device *dev, void *data,
523+ struct drm_file *file_priv)
524+{
525+ struct drm_gem_open *args = data;
526+ struct drm_gem_object *obj;
527+ int ret;
528+ int handle;
529+
530+ if (!(dev->driver->driver_features & DRIVER_GEM))
531+ return -ENODEV;
532+
533+ spin_lock(&dev->object_name_lock);
534+ obj = idr_find(&dev->object_name_idr, (int) args->name);
535+ if (obj)
536+ drm_gem_object_reference(obj);
537+ spin_unlock(&dev->object_name_lock);
538+ if (!obj)
539+ return -ENOENT;
540+
541+ ret = drm_gem_handle_create(file_priv, obj, &handle);
542+ mutex_lock(&dev->struct_mutex);
543+ drm_gem_object_unreference(obj);
544+ mutex_unlock(&dev->struct_mutex);
545+ if (ret)
546+ return ret;
547+
548+ args->handle = handle;
549+ args->size = obj->size;
550+
551+ return 0;
552+}
553+
554+/**
555+ * Called at device open time, sets up the structure for handling refcounting
556+ * of mm objects.
557+ */
558+void
559+drm_gem_open(struct drm_device *dev, struct drm_file *file_private)
560+{
561+ idr_init(&file_private->object_idr);
562+ spin_lock_init(&file_private->table_lock);
563+}
564+
565+/**
566+ * Called at device close to release the file's
567+ * handle references on objects.
568+ */
569+static int
570+drm_gem_object_release_handle(int id, void *ptr, void *data)
571+{
572+ struct drm_gem_object *obj = ptr;
573+
574+ drm_gem_object_handle_unreference(obj);
575+
576+ return 0;
577+}
578+
579+/**
580+ * Called at close time when the filp is going away.
581+ *
582+ * Releases any remaining references on objects by this filp.
583+ */
584+void
585+drm_gem_release(struct drm_device *dev, struct drm_file *file_private)
586+{
587+ mutex_lock(&dev->struct_mutex);
588+ idr_for_each(&file_private->object_idr,
589+ &drm_gem_object_release_handle, NULL);
590+
591+ idr_destroy(&file_private->object_idr);
592+ mutex_unlock(&dev->struct_mutex);
593+}
594+
595+/**
596+ * Called after the last reference to the object has been lost.
597+ *
598+ * Frees the object
599+ */
600+void
601+drm_gem_object_free(struct kref *kref)
602+{
603+ struct drm_gem_object *obj = (struct drm_gem_object *) kref;
604+ struct drm_device *dev = obj->dev;
605+
606+ BUG_ON(!mutex_is_locked(&dev->struct_mutex));
607+
608+ if (dev->driver->gem_free_object != NULL)
609+ dev->driver->gem_free_object(obj);
610+
611+ fput(obj->filp);
612+ atomic_dec(&dev->object_count);
613+ atomic_sub(obj->size, &dev->object_memory);
614+ kfree(obj);
615+}
616+EXPORT_SYMBOL(drm_gem_object_free);
617+
618+/**
619+ * Called after the last handle to the object has been closed
620+ *
621+ * Removes any name for the object. Note that this must be
622+ * called before drm_gem_object_free or we'll be touching
623+ * freed memory
624+ */
625+void
626+drm_gem_object_handle_free(struct kref *kref)
627+{
628+ struct drm_gem_object *obj = container_of(kref,
629+ struct drm_gem_object,
630+ handlecount);
631+ struct drm_device *dev = obj->dev;
632+
633+ /* Remove any name for this object */
634+ spin_lock(&dev->object_name_lock);
635+ if (obj->name) {
636+ idr_remove(&dev->object_name_idr, obj->name);
637+ spin_unlock(&dev->object_name_lock);
638+ /*
639+ * The object name held a reference to this object, drop
640+ * that now.
641+ */
642+ drm_gem_object_unreference(obj);
643+ } else
644+ spin_unlock(&dev->object_name_lock);
645+
646+}
647+EXPORT_SYMBOL(drm_gem_object_handle_free);
648+
649diff --git a/drivers/gpu/drm/drm_memory.c b/drivers/gpu/drm/drm_memory.c
650index 0177012..803bc9e 100644
651--- a/drivers/gpu/drm/drm_memory.c
652+++ b/drivers/gpu/drm/drm_memory.c
653@@ -133,6 +133,7 @@ int drm_free_agp(DRM_AGP_MEM * handle, int pages)
654 {
655 return drm_agp_free_memory(handle) ? 0 : -EINVAL;
656 }
657+EXPORT_SYMBOL(drm_free_agp);
658
659 /** Wrapper around agp_bind_memory() */
660 int drm_bind_agp(DRM_AGP_MEM * handle, unsigned int start)
661@@ -145,6 +146,7 @@ int drm_unbind_agp(DRM_AGP_MEM * handle)
662 {
663 return drm_agp_unbind_memory(handle);
664 }
665+EXPORT_SYMBOL(drm_unbind_agp);
666
667 #else /* __OS_HAS_AGP */
668 static inline void *agp_remap(unsigned long offset, unsigned long size,
669diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
670index dcff9e9..217ad7d 100644
671--- a/drivers/gpu/drm/drm_mm.c
672+++ b/drivers/gpu/drm/drm_mm.c
673@@ -169,6 +169,7 @@ struct drm_mm_node *drm_mm_get_block(struct drm_mm_node * parent,
674
675 return child;
676 }
677+EXPORT_SYMBOL(drm_mm_get_block);
678
679 /*
680 * Put a block. Merge with the previous and / or next block if they are free.
681@@ -217,6 +218,7 @@ void drm_mm_put_block(struct drm_mm_node * cur)
682 drm_free(cur, sizeof(*cur), DRM_MEM_MM);
683 }
684 }
685+EXPORT_SYMBOL(drm_mm_put_block);
686
687 struct drm_mm_node *drm_mm_search_free(const struct drm_mm * mm,
688 unsigned long size,
689@@ -265,6 +267,7 @@ int drm_mm_clean(struct drm_mm * mm)
690
691 return (head->next->next == head);
692 }
693+EXPORT_SYMBOL(drm_mm_search_free);
694
695 int drm_mm_init(struct drm_mm * mm, unsigned long start, unsigned long size)
696 {
697@@ -273,7 +276,7 @@ int drm_mm_init(struct drm_mm * mm, unsigned long start, unsigned long size)
698
699 return drm_mm_create_tail_node(mm, start, size);
700 }
701-
702+EXPORT_SYMBOL(drm_mm_init);
703
704 void drm_mm_takedown(struct drm_mm * mm)
705 {
706diff --git a/drivers/gpu/drm/drm_proc.c b/drivers/gpu/drm/drm_proc.c
707index 93b1e04..d490db4 100644
708--- a/drivers/gpu/drm/drm_proc.c
709+++ b/drivers/gpu/drm/drm_proc.c
710@@ -49,6 +49,10 @@ static int drm_queues_info(char *buf, char **start, off_t offset,
711 int request, int *eof, void *data);
712 static int drm_bufs_info(char *buf, char **start, off_t offset,
713 int request, int *eof, void *data);
714+static int drm_gem_name_info(char *buf, char **start, off_t offset,
715+ int request, int *eof, void *data);
716+static int drm_gem_object_info(char *buf, char **start, off_t offset,
717+ int request, int *eof, void *data);
718 #if DRM_DEBUG_CODE
719 static int drm_vma_info(char *buf, char **start, off_t offset,
720 int request, int *eof, void *data);
721@@ -60,13 +64,16 @@ static int drm_vma_info(char *buf, char **start, off_t offset,
722 static struct drm_proc_list {
723 const char *name; /**< file name */
724 int (*f) (char *, char **, off_t, int, int *, void *); /**< proc callback*/
725+ u32 driver_features; /**< Required driver features for this entry */
726 } drm_proc_list[] = {
727- {"name", drm_name_info},
728- {"mem", drm_mem_info},
729- {"vm", drm_vm_info},
730- {"clients", drm_clients_info},
731- {"queues", drm_queues_info},
732- {"bufs", drm_bufs_info},
733+ {"name", drm_name_info, 0},
734+ {"mem", drm_mem_info, 0},
735+ {"vm", drm_vm_info, 0},
736+ {"clients", drm_clients_info, 0},
737+ {"queues", drm_queues_info, 0},
738+ {"bufs", drm_bufs_info, 0},
739+ {"gem_names", drm_gem_name_info, DRIVER_GEM},
740+ {"gem_objects", drm_gem_object_info, DRIVER_GEM},
741 #if DRM_DEBUG_CODE
742 {"vma", drm_vma_info},
743 #endif
744@@ -90,8 +97,9 @@ static struct drm_proc_list {
745 int drm_proc_init(struct drm_minor *minor, int minor_id,
746 struct proc_dir_entry *root)
747 {
748+ struct drm_device *dev = minor->dev;
749 struct proc_dir_entry *ent;
750- int i, j;
751+ int i, j, ret;
752 char name[64];
753
754 sprintf(name, "%d", minor_id);
755@@ -102,23 +110,42 @@ int drm_proc_init(struct drm_minor *minor, int minor_id,
756 }
757
758 for (i = 0; i < DRM_PROC_ENTRIES; i++) {
759+ u32 features = drm_proc_list[i].driver_features;
760+
761+ if (features != 0 &&
762+ (dev->driver->driver_features & features) != features)
763+ continue;
764+
765 ent = create_proc_entry(drm_proc_list[i].name,
766 S_IFREG | S_IRUGO, minor->dev_root);
767 if (!ent) {
768 DRM_ERROR("Cannot create /proc/dri/%s/%s\n",
769 name, drm_proc_list[i].name);
770- for (j = 0; j < i; j++)
771- remove_proc_entry(drm_proc_list[i].name,
772- minor->dev_root);
773- remove_proc_entry(name, root);
774- minor->dev_root = NULL;
775- return -1;
776+ ret = -1;
777+ goto fail;
778 }
779 ent->read_proc = drm_proc_list[i].f;
780 ent->data = minor;
781 }
782
783+ if (dev->driver->proc_init) {
784+ ret = dev->driver->proc_init(minor);
785+ if (ret) {
786+ DRM_ERROR("DRM: Driver failed to initialize "
787+ "/proc/dri.\n");
788+ goto fail;
789+ }
790+ }
791+
792 return 0;
793+ fail:
794+
795+ for (j = 0; j < i; j++)
796+ remove_proc_entry(drm_proc_list[i].name,
797+ minor->dev_root);
798+ remove_proc_entry(name, root);
799+ minor->dev_root = NULL;
800+ return ret;
801 }
802
803 /**
804@@ -133,12 +160,16 @@ int drm_proc_init(struct drm_minor *minor, int minor_id,
805 */
806 int drm_proc_cleanup(struct drm_minor *minor, struct proc_dir_entry *root)
807 {
808+ struct drm_device *dev = minor->dev;
809 int i;
810 char name[64];
811
812 if (!root || !minor->dev_root)
813 return 0;
814
815+ if (dev->driver->proc_cleanup)
816+ dev->driver->proc_cleanup(minor);
817+
818 for (i = 0; i < DRM_PROC_ENTRIES; i++)
819 remove_proc_entry(drm_proc_list[i].name, minor->dev_root);
820 sprintf(name, "%d", minor->index);
821@@ -480,6 +511,84 @@ static int drm_clients_info(char *buf, char **start, off_t offset,
822 return ret;
823 }
824
825+struct drm_gem_name_info_data {
826+ int len;
827+ char *buf;
828+ int eof;
829+};
830+
831+static int drm_gem_one_name_info(int id, void *ptr, void *data)
832+{
833+ struct drm_gem_object *obj = ptr;
834+ struct drm_gem_name_info_data *nid = data;
835+
836+ DRM_INFO("name %d size %d\n", obj->name, obj->size);
837+ if (nid->eof)
838+ return 0;
839+
840+ nid->len += sprintf(&nid->buf[nid->len],
841+ "%6d%9d%8d%9d\n",
842+ obj->name, obj->size,
843+ atomic_read(&obj->handlecount.refcount),
844+ atomic_read(&obj->refcount.refcount));
845+ if (nid->len > DRM_PROC_LIMIT) {
846+ nid->eof = 1;
847+ return 0;
848+ }
849+ return 0;
850+}
851+
852+static int drm_gem_name_info(char *buf, char **start, off_t offset,
853+ int request, int *eof, void *data)
854+{
855+ struct drm_minor *minor = (struct drm_minor *) data;
856+ struct drm_device *dev = minor->dev;
857+ struct drm_gem_name_info_data nid;
858+
859+ if (offset > DRM_PROC_LIMIT) {
860+ *eof = 1;
861+ return 0;
862+ }
863+
864+ nid.len = sprintf(buf, " name size handles refcount\n");
865+ nid.buf = buf;
866+ nid.eof = 0;
867+ idr_for_each(&dev->object_name_idr, drm_gem_one_name_info, &nid);
868+
869+ *start = &buf[offset];
870+ *eof = 0;
871+ if (nid.len > request + offset)
872+ return request;
873+ *eof = 1;
874+ return nid.len - offset;
875+}
876+
877+static int drm_gem_object_info(char *buf, char **start, off_t offset,
878+ int request, int *eof, void *data)
879+{
880+ struct drm_minor *minor = (struct drm_minor *) data;
881+ struct drm_device *dev = minor->dev;
882+ int len = 0;
883+
884+ if (offset > DRM_PROC_LIMIT) {
885+ *eof = 1;
886+ return 0;
887+ }
888+
889+ *start = &buf[offset];
890+ *eof = 0;
891+ DRM_PROC_PRINT("%d objects\n", atomic_read(&dev->object_count));
892+ DRM_PROC_PRINT("%d object bytes\n", atomic_read(&dev->object_memory));
893+ DRM_PROC_PRINT("%d pinned\n", atomic_read(&dev->pin_count));
894+ DRM_PROC_PRINT("%d pin bytes\n", atomic_read(&dev->pin_memory));
895+ DRM_PROC_PRINT("%d gtt bytes\n", atomic_read(&dev->gtt_memory));
896+ DRM_PROC_PRINT("%d gtt total\n", dev->gtt_total);
897+ if (len > request + offset)
898+ return request;
899+ *eof = 1;
900+ return len - offset;
901+}
902+
903 #if DRM_DEBUG_CODE
904
905 static int drm__vma_info(char *buf, char **start, off_t offset, int request,
906diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c
907index c2f584f..82f4657 100644
908--- a/drivers/gpu/drm/drm_stub.c
909+++ b/drivers/gpu/drm/drm_stub.c
910@@ -152,6 +152,15 @@ static int drm_fill_in_dev(struct drm_device * dev, struct pci_dev *pdev,
911 goto error_out_unreg;
912 }
913
914+ if (driver->driver_features & DRIVER_GEM) {
915+ retcode = drm_gem_init(dev);
916+ if (retcode) {
917+ DRM_ERROR("Cannot initialize graphics execution "
918+ "manager (GEM)\n");
919+ goto error_out_unreg;
920+ }
921+ }
922+
923 return 0;
924
925 error_out_unreg:
926@@ -317,6 +326,7 @@ int drm_put_dev(struct drm_device * dev)
927 int drm_put_minor(struct drm_minor **minor_p)
928 {
929 struct drm_minor *minor = *minor_p;
930+
931 DRM_DEBUG("release secondary minor %d\n", minor->index);
932
933 if (minor->type == DRM_MINOR_LEGACY)
934diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
935index c4bbda6..5ba78e4 100644
936--- a/drivers/gpu/drm/i915/Makefile
937+++ b/drivers/gpu/drm/i915/Makefile
938@@ -4,7 +4,11 @@
939
940 ccflags-y := -Iinclude/drm
941 i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o i915_opregion.o \
942- i915_suspend.o
943+ i915_suspend.o \
944+ i915_gem.o \
945+ i915_gem_debug.o \
946+ i915_gem_proc.o \
947+ i915_gem_tiling.o
948
949 i915-$(CONFIG_COMPAT) += i915_ioc32.o
950
951diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
952index 8609ec2..3b5aa74 100644
953--- a/drivers/gpu/drm/i915/i915_dma.c
954+++ b/drivers/gpu/drm/i915/i915_dma.c
955@@ -170,24 +170,31 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
956 dev_priv->sarea_priv = (drm_i915_sarea_t *)
957 ((u8 *) dev_priv->sarea->handle + init->sarea_priv_offset);
958
959- dev_priv->ring.Start = init->ring_start;
960- dev_priv->ring.End = init->ring_end;
961- dev_priv->ring.Size = init->ring_size;
962- dev_priv->ring.tail_mask = dev_priv->ring.Size - 1;
963+ if (init->ring_size != 0) {
964+ if (dev_priv->ring.ring_obj != NULL) {
965+ i915_dma_cleanup(dev);
966+ DRM_ERROR("Client tried to initialize ringbuffer in "
967+ "GEM mode\n");
968+ return -EINVAL;
969+ }
970
971- dev_priv->ring.map.offset = init->ring_start;
972- dev_priv->ring.map.size = init->ring_size;
973- dev_priv->ring.map.type = 0;
974- dev_priv->ring.map.flags = 0;
975- dev_priv->ring.map.mtrr = 0;
976+ dev_priv->ring.Size = init->ring_size;
977+ dev_priv->ring.tail_mask = dev_priv->ring.Size - 1;
978
979- drm_core_ioremap(&dev_priv->ring.map, dev);
980+ dev_priv->ring.map.offset = init->ring_start;
981+ dev_priv->ring.map.size = init->ring_size;
982+ dev_priv->ring.map.type = 0;
983+ dev_priv->ring.map.flags = 0;
984+ dev_priv->ring.map.mtrr = 0;
985
986- if (dev_priv->ring.map.handle == NULL) {
987- i915_dma_cleanup(dev);
988- DRM_ERROR("can not ioremap virtual address for"
989- " ring buffer\n");
990- return -ENOMEM;
991+ drm_core_ioremap(&dev_priv->ring.map, dev);
992+
993+ if (dev_priv->ring.map.handle == NULL) {
994+ i915_dma_cleanup(dev);
995+ DRM_ERROR("can not ioremap virtual address for"
996+ " ring buffer\n");
997+ return -ENOMEM;
998+ }
999 }
1000
1001 dev_priv->ring.virtual_start = dev_priv->ring.map.handle;
1002@@ -377,9 +384,10 @@ static int i915_emit_cmds(struct drm_device * dev, int __user * buffer, int dwor
1003 return 0;
1004 }
1005
1006-static int i915_emit_box(struct drm_device * dev,
1007- struct drm_clip_rect __user * boxes,
1008- int i, int DR1, int DR4)
1009+int
1010+i915_emit_box(struct drm_device *dev,
1011+ struct drm_clip_rect __user *boxes,
1012+ int i, int DR1, int DR4)
1013 {
1014 drm_i915_private_t *dev_priv = dev->dev_private;
1015 struct drm_clip_rect box;
1016@@ -681,6 +689,9 @@ static int i915_getparam(struct drm_device *dev, void *data,
1017 case I915_PARAM_LAST_DISPATCH:
1018 value = READ_BREADCRUMB(dev_priv);
1019 break;
1020+ case I915_PARAM_HAS_GEM:
1021+ value = 1;
1022+ break;
1023 default:
1024 DRM_ERROR("Unknown parameter %d\n", param->param);
1025 return -EINVAL;
1026@@ -784,6 +795,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
1027 memset(dev_priv, 0, sizeof(drm_i915_private_t));
1028
1029 dev->dev_private = (void *)dev_priv;
1030+ dev_priv->dev = dev;
1031
1032 /* Add register map (needed for suspend/resume) */
1033 base = drm_get_resource_start(dev, mmio_bar);
1034@@ -793,6 +805,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
1035 _DRM_KERNEL | _DRM_DRIVER,
1036 &dev_priv->mmio_map);
1037
1038+ i915_gem_load(dev);
1039+
1040 /* Init HWS */
1041 if (!I915_NEED_GFX_HWS(dev)) {
1042 ret = i915_init_phys_hws(dev);
1043@@ -838,6 +852,25 @@ int i915_driver_unload(struct drm_device *dev)
1044 return 0;
1045 }
1046
1047+int i915_driver_open(struct drm_device *dev, struct drm_file *file_priv)
1048+{
1049+ struct drm_i915_file_private *i915_file_priv;
1050+
1051+ DRM_DEBUG("\n");
1052+ i915_file_priv = (struct drm_i915_file_private *)
1053+ drm_alloc(sizeof(*i915_file_priv), DRM_MEM_FILES);
1054+
1055+ if (!i915_file_priv)
1056+ return -ENOMEM;
1057+
1058+ file_priv->driver_priv = i915_file_priv;
1059+
1060+ i915_file_priv->mm.last_gem_seqno = 0;
1061+ i915_file_priv->mm.last_gem_throttle_seqno = 0;
1062+
1063+ return 0;
1064+}
1065+
1066 void i915_driver_lastclose(struct drm_device * dev)
1067 {
1068 drm_i915_private_t *dev_priv = dev->dev_private;
1069@@ -845,6 +878,8 @@ void i915_driver_lastclose(struct drm_device * dev)
1070 if (!dev_priv)
1071 return;
1072
1073+ i915_gem_lastclose(dev);
1074+
1075 if (dev_priv->agp_heap)
1076 i915_mem_takedown(&(dev_priv->agp_heap));
1077
1078@@ -857,6 +892,13 @@ void i915_driver_preclose(struct drm_device * dev, struct drm_file *file_priv)
1079 i915_mem_release(dev, file_priv, dev_priv->agp_heap);
1080 }
1081
1082+void i915_driver_postclose(struct drm_device *dev, struct drm_file *file_priv)
1083+{
1084+ struct drm_i915_file_private *i915_file_priv = file_priv->driver_priv;
1085+
1086+ drm_free(i915_file_priv, sizeof(*i915_file_priv), DRM_MEM_FILES);
1087+}
1088+
1089 struct drm_ioctl_desc i915_ioctls[] = {
1090 DRM_IOCTL_DEF(DRM_I915_INIT, i915_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
1091 DRM_IOCTL_DEF(DRM_I915_FLUSH, i915_flush_ioctl, DRM_AUTH),
1092@@ -875,6 +917,22 @@ struct drm_ioctl_desc i915_ioctls[] = {
1093 DRM_IOCTL_DEF(DRM_I915_GET_VBLANK_PIPE, i915_vblank_pipe_get, DRM_AUTH ),
1094 DRM_IOCTL_DEF(DRM_I915_VBLANK_SWAP, i915_vblank_swap, DRM_AUTH),
1095 DRM_IOCTL_DEF(DRM_I915_HWS_ADDR, i915_set_status_page, DRM_AUTH),
1096+ DRM_IOCTL_DEF(DRM_I915_GEM_INIT, i915_gem_init_ioctl, DRM_AUTH),
1097+ DRM_IOCTL_DEF(DRM_I915_GEM_EXECBUFFER, i915_gem_execbuffer, DRM_AUTH),
1098+ DRM_IOCTL_DEF(DRM_I915_GEM_PIN, i915_gem_pin_ioctl, DRM_AUTH|DRM_ROOT_ONLY),
1099+ DRM_IOCTL_DEF(DRM_I915_GEM_UNPIN, i915_gem_unpin_ioctl, DRM_AUTH|DRM_ROOT_ONLY),
1100+ DRM_IOCTL_DEF(DRM_I915_GEM_BUSY, i915_gem_busy_ioctl, DRM_AUTH),
1101+ DRM_IOCTL_DEF(DRM_I915_GEM_THROTTLE, i915_gem_throttle_ioctl, DRM_AUTH),
1102+ DRM_IOCTL_DEF(DRM_I915_GEM_ENTERVT, i915_gem_entervt_ioctl, DRM_AUTH),
1103+ DRM_IOCTL_DEF(DRM_I915_GEM_LEAVEVT, i915_gem_leavevt_ioctl, DRM_AUTH),
1104+ DRM_IOCTL_DEF(DRM_I915_GEM_CREATE, i915_gem_create_ioctl, 0),
1105+ DRM_IOCTL_DEF(DRM_I915_GEM_PREAD, i915_gem_pread_ioctl, 0),
1106+ DRM_IOCTL_DEF(DRM_I915_GEM_PWRITE, i915_gem_pwrite_ioctl, 0),
1107+ DRM_IOCTL_DEF(DRM_I915_GEM_MMAP, i915_gem_mmap_ioctl, 0),
1108+ DRM_IOCTL_DEF(DRM_I915_GEM_SET_DOMAIN, i915_gem_set_domain_ioctl, 0),
1109+ DRM_IOCTL_DEF(DRM_I915_GEM_SW_FINISH, i915_gem_sw_finish_ioctl, 0),
1110+ DRM_IOCTL_DEF(DRM_I915_GEM_SET_TILING, i915_gem_set_tiling, 0),
1111+ DRM_IOCTL_DEF(DRM_I915_GEM_GET_TILING, i915_gem_get_tiling, 0),
1112 };
1113
1114 int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls);
1115diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
1116index 37af03f..a80ead2 100644
1117--- a/drivers/gpu/drm/i915/i915_drv.c
1118+++ b/drivers/gpu/drm/i915/i915_drv.c
1119@@ -85,12 +85,15 @@ static struct drm_driver driver = {
1120 /* don't use mtrr's here, the Xserver or user space app should
1121 * deal with them for intel hardware.
1122 */
1123- .driver_features = DRIVER_USE_AGP | DRIVER_REQUIRE_AGP |
1124- DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED,
1125+ .driver_features =
1126+ DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | /* DRIVER_USE_MTRR |*/
1127+ DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM,
1128 .load = i915_driver_load,
1129 .unload = i915_driver_unload,
1130+ .open = i915_driver_open,
1131 .lastclose = i915_driver_lastclose,
1132 .preclose = i915_driver_preclose,
1133+ .postclose = i915_driver_postclose,
1134 .suspend = i915_suspend,
1135 .resume = i915_resume,
1136 .device_is_agp = i915_driver_device_is_agp,
1137@@ -104,6 +107,10 @@ static struct drm_driver driver = {
1138 .reclaim_buffers = drm_core_reclaim_buffers,
1139 .get_map_ofs = drm_core_get_map_ofs,
1140 .get_reg_ofs = drm_core_get_reg_ofs,
1141+ .proc_init = i915_gem_proc_init,
1142+ .proc_cleanup = i915_gem_proc_cleanup,
1143+ .gem_init_object = i915_gem_init_object,
1144+ .gem_free_object = i915_gem_free_object,
1145 .ioctls = i915_ioctls,
1146 .fops = {
1147 .owner = THIS_MODULE,
1148diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
1149index d1a02be..87b071a 100644
1150--- a/drivers/gpu/drm/i915/i915_drv.h
1151+++ b/drivers/gpu/drm/i915/i915_drv.h
1152@@ -39,7 +39,7 @@
1153
1154 #define DRIVER_NAME "i915"
1155 #define DRIVER_DESC "Intel Graphics"
1156-#define DRIVER_DATE "20060119"
1157+#define DRIVER_DATE "20080730"
1158
1159 enum pipe {
1160 PIPE_A = 0,
1161@@ -60,16 +60,23 @@ enum pipe {
1162 #define DRIVER_MINOR 6
1163 #define DRIVER_PATCHLEVEL 0
1164
1165+#define WATCH_COHERENCY 0
1166+#define WATCH_BUF 0
1167+#define WATCH_EXEC 0
1168+#define WATCH_LRU 0
1169+#define WATCH_RELOC 0
1170+#define WATCH_INACTIVE 0
1171+#define WATCH_PWRITE 0
1172+
1173 typedef struct _drm_i915_ring_buffer {
1174 int tail_mask;
1175- unsigned long Start;
1176- unsigned long End;
1177 unsigned long Size;
1178 u8 *virtual_start;
1179 int head;
1180 int tail;
1181 int space;
1182 drm_local_map_t map;
1183+ struct drm_gem_object *ring_obj;
1184 } drm_i915_ring_buffer_t;
1185
1186 struct mem_block {
1187@@ -101,6 +108,8 @@ struct intel_opregion {
1188 };
1189
1190 typedef struct drm_i915_private {
1191+ struct drm_device *dev;
1192+
1193 drm_local_map_t *sarea;
1194 drm_local_map_t *mmio_map;
1195
1196@@ -113,6 +122,7 @@ typedef struct drm_i915_private {
1197 uint32_t counter;
1198 unsigned int status_gfx_addr;
1199 drm_local_map_t hws_map;
1200+ struct drm_gem_object *hws_obj;
1201
1202 unsigned int cpp;
1203 int back_offset;
1204@@ -122,7 +132,6 @@ typedef struct drm_i915_private {
1205
1206 wait_queue_head_t irq_queue;
1207 atomic_t irq_received;
1208- atomic_t irq_emitted;
1209 /** Protects user_irq_refcount and irq_mask_reg */
1210 spinlock_t user_irq_lock;
1211 /** Refcount for i915_user_irq_get() versus i915_user_irq_put(). */
1212@@ -230,8 +239,174 @@ typedef struct drm_i915_private {
1213 u8 saveDACMASK;
1214 u8 saveDACDATA[256*3]; /* 256 3-byte colors */
1215 u8 saveCR[37];
1216+
1217+ struct {
1218+ struct drm_mm gtt_space;
1219+
1220+ /**
1221+ * List of objects currently involved in rendering from the
1222+ * ringbuffer.
1223+ *
1224+ * A reference is held on the buffer while on this list.
1225+ */
1226+ struct list_head active_list;
1227+
1228+ /**
1229+ * List of objects which are not in the ringbuffer but which
1230+ * still have a write_domain which needs to be flushed before
1231+ * unbinding.
1232+ *
1233+ * A reference is held on the buffer while on this list.
1234+ */
1235+ struct list_head flushing_list;
1236+
1237+ /**
1238+ * LRU list of objects which are not in the ringbuffer and
1239+ * are ready to unbind, but are still in the GTT.
1240+ *
1241+ * A reference is not held on the buffer while on this list,
1242+ * as merely being GTT-bound shouldn't prevent its being
1243+ * freed, and we'll pull it off the list in the free path.
1244+ */
1245+ struct list_head inactive_list;
1246+
1247+ /**
1248+ * List of breadcrumbs associated with GPU requests currently
1249+ * outstanding.
1250+ */
1251+ struct list_head request_list;
1252+
1253+ /**
1254+ * We leave the user IRQ off as much as possible,
1255+ * but this means that requests will finish and never
1256+ * be retired once the system goes idle. Set a timer to
1257+ * fire periodically while the ring is running. When it
1258+ * fires, go retire requests.
1259+ */
1260+ struct delayed_work retire_work;
1261+
1262+ uint32_t next_gem_seqno;
1263+
1264+ /**
1265+ * Waiting sequence number, if any
1266+ */
1267+ uint32_t waiting_gem_seqno;
1268+
1269+ /**
1270+ * Last seq seen at irq time
1271+ */
1272+ uint32_t irq_gem_seqno;
1273+
1274+ /**
1275+ * Flag if the X Server, and thus DRM, is not currently in
1276+ * control of the device.
1277+ *
1278+ * This is set between LeaveVT and EnterVT. It needs to be
1279+ * replaced with a semaphore. It also needs to be
1280+ * transitioned away from for kernel modesetting.
1281+ */
1282+ int suspended;
1283+
1284+ /**
1285+ * Flag if the hardware appears to be wedged.
1286+ *
1287+ * This is set when attempts to idle the device timeout.
1288+ * It prevents command submission from occuring and makes
1289+ * every pending request fail
1290+ */
1291+ int wedged;
1292+
1293+ /** Bit 6 swizzling required for X tiling */
1294+ uint32_t bit_6_swizzle_x;
1295+ /** Bit 6 swizzling required for Y tiling */
1296+ uint32_t bit_6_swizzle_y;
1297+ } mm;
1298 } drm_i915_private_t;
1299
1300+/** driver private structure attached to each drm_gem_object */
1301+struct drm_i915_gem_object {
1302+ struct drm_gem_object *obj;
1303+
1304+ /** Current space allocated to this object in the GTT, if any. */
1305+ struct drm_mm_node *gtt_space;
1306+
1307+ /** This object's place on the active/flushing/inactive lists */
1308+ struct list_head list;
1309+
1310+ /**
1311+ * This is set if the object is on the active or flushing lists
1312+ * (has pending rendering), and is not set if it's on inactive (ready
1313+ * to be unbound).
1314+ */
1315+ int active;
1316+
1317+ /**
1318+ * This is set if the object has been written to since last bound
1319+ * to the GTT
1320+ */
1321+ int dirty;
1322+
1323+ /** AGP memory structure for our GTT binding. */
1324+ DRM_AGP_MEM *agp_mem;
1325+
1326+ struct page **page_list;
1327+
1328+ /**
1329+ * Current offset of the object in GTT space.
1330+ *
1331+ * This is the same as gtt_space->start
1332+ */
1333+ uint32_t gtt_offset;
1334+
1335+ /** Boolean whether this object has a valid gtt offset. */
1336+ int gtt_bound;
1337+
1338+ /** How many users have pinned this object in GTT space */
1339+ int pin_count;
1340+
1341+ /** Breadcrumb of last rendering to the buffer. */
1342+ uint32_t last_rendering_seqno;
1343+
1344+ /** Current tiling mode for the object. */
1345+ uint32_t tiling_mode;
1346+
1347+ /**
1348+ * Flagging of which individual pages are valid in GEM_DOMAIN_CPU when
1349+ * GEM_DOMAIN_CPU is not in the object's read domain.
1350+ */
1351+ uint8_t *page_cpu_valid;
1352+};
1353+
1354+/**
1355+ * Request queue structure.
1356+ *
1357+ * The request queue allows us to note sequence numbers that have been emitted
1358+ * and may be associated with active buffers to be retired.
1359+ *
1360+ * By keeping this list, we can avoid having to do questionable
1361+ * sequence-number comparisons on buffer last_rendering_seqnos, and associate
1362+ * an emission time with seqnos for tracking how far ahead of the GPU we are.
1363+ */
1364+struct drm_i915_gem_request {
1365+ /** GEM sequence number associated with this request. */
1366+ uint32_t seqno;
1367+
1368+ /** Time at which this request was emitted, in jiffies. */
1369+ unsigned long emitted_jiffies;
1370+
1371+ /** Cache domains that were flushed at the start of the request. */
1372+ uint32_t flush_domains;
1373+
1374+ struct list_head list;
1375+};
1376+
1377+struct drm_i915_file_private {
1378+ struct {
1379+ uint32_t last_gem_seqno;
1380+ uint32_t last_gem_throttle_seqno;
1381+ } mm;
1382+};
1383+
1384 extern struct drm_ioctl_desc i915_ioctls[];
1385 extern int i915_max_ioctl;
1386
1387@@ -239,18 +414,26 @@ extern int i915_max_ioctl;
1388 extern void i915_kernel_lost_context(struct drm_device * dev);
1389 extern int i915_driver_load(struct drm_device *, unsigned long flags);
1390 extern int i915_driver_unload(struct drm_device *);
1391+extern int i915_driver_open(struct drm_device *dev, struct drm_file *file_priv);
1392 extern void i915_driver_lastclose(struct drm_device * dev);
1393 extern void i915_driver_preclose(struct drm_device *dev,
1394 struct drm_file *file_priv);
1395+extern void i915_driver_postclose(struct drm_device *dev,
1396+ struct drm_file *file_priv);
1397 extern int i915_driver_device_is_agp(struct drm_device * dev);
1398 extern long i915_compat_ioctl(struct file *filp, unsigned int cmd,
1399 unsigned long arg);
1400+extern int i915_emit_box(struct drm_device *dev,
1401+ struct drm_clip_rect __user *boxes,
1402+ int i, int DR1, int DR4);
1403
1404 /* i915_irq.c */
1405 extern int i915_irq_emit(struct drm_device *dev, void *data,
1406 struct drm_file *file_priv);
1407 extern int i915_irq_wait(struct drm_device *dev, void *data,
1408 struct drm_file *file_priv);
1409+void i915_user_irq_get(struct drm_device *dev);
1410+void i915_user_irq_put(struct drm_device *dev);
1411
1412 extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS);
1413 extern void i915_driver_irq_preinstall(struct drm_device * dev);
1414@@ -279,6 +462,67 @@ extern int i915_mem_destroy_heap(struct drm_device *dev, void *data,
1415 extern void i915_mem_takedown(struct mem_block **heap);
1416 extern void i915_mem_release(struct drm_device * dev,
1417 struct drm_file *file_priv, struct mem_block *heap);
1418+/* i915_gem.c */
1419+int i915_gem_init_ioctl(struct drm_device *dev, void *data,
1420+ struct drm_file *file_priv);
1421+int i915_gem_create_ioctl(struct drm_device *dev, void *data,
1422+ struct drm_file *file_priv);
1423+int i915_gem_pread_ioctl(struct drm_device *dev, void *data,
1424+ struct drm_file *file_priv);
1425+int i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
1426+ struct drm_file *file_priv);
1427+int i915_gem_mmap_ioctl(struct drm_device *dev, void *data,
1428+ struct drm_file *file_priv);
1429+int i915_gem_set_domain_ioctl(struct drm_device *dev, void *data,
1430+ struct drm_file *file_priv);
1431+int i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data,
1432+ struct drm_file *file_priv);
1433+int i915_gem_execbuffer(struct drm_device *dev, void *data,
1434+ struct drm_file *file_priv);
1435+int i915_gem_pin_ioctl(struct drm_device *dev, void *data,
1436+ struct drm_file *file_priv);
1437+int i915_gem_unpin_ioctl(struct drm_device *dev, void *data,
1438+ struct drm_file *file_priv);
1439+int i915_gem_busy_ioctl(struct drm_device *dev, void *data,
1440+ struct drm_file *file_priv);
1441+int i915_gem_throttle_ioctl(struct drm_device *dev, void *data,
1442+ struct drm_file *file_priv);
1443+int i915_gem_entervt_ioctl(struct drm_device *dev, void *data,
1444+ struct drm_file *file_priv);
1445+int i915_gem_leavevt_ioctl(struct drm_device *dev, void *data,
1446+ struct drm_file *file_priv);
1447+int i915_gem_set_tiling(struct drm_device *dev, void *data,
1448+ struct drm_file *file_priv);
1449+int i915_gem_get_tiling(struct drm_device *dev, void *data,
1450+ struct drm_file *file_priv);
1451+void i915_gem_load(struct drm_device *dev);
1452+int i915_gem_proc_init(struct drm_minor *minor);
1453+void i915_gem_proc_cleanup(struct drm_minor *minor);
1454+int i915_gem_init_object(struct drm_gem_object *obj);
1455+void i915_gem_free_object(struct drm_gem_object *obj);
1456+int i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment);
1457+void i915_gem_object_unpin(struct drm_gem_object *obj);
1458+void i915_gem_lastclose(struct drm_device *dev);
1459+uint32_t i915_get_gem_seqno(struct drm_device *dev);
1460+void i915_gem_retire_requests(struct drm_device *dev);
1461+void i915_gem_retire_work_handler(struct work_struct *work);
1462+void i915_gem_clflush_object(struct drm_gem_object *obj);
1463+
1464+/* i915_gem_tiling.c */
1465+void i915_gem_detect_bit_6_swizzle(struct drm_device *dev);
1466+
1467+/* i915_gem_debug.c */
1468+void i915_gem_dump_object(struct drm_gem_object *obj, int len,
1469+ const char *where, uint32_t mark);
1470+#if WATCH_INACTIVE
1471+void i915_verify_inactive(struct drm_device *dev, char *file, int line);
1472+#else
1473+#define i915_verify_inactive(dev, file, line)
1474+#endif
1475+void i915_gem_object_check_coherency(struct drm_gem_object *obj, int handle);
1476+void i915_gem_dump_object(struct drm_gem_object *obj, int len,
1477+ const char *where, uint32_t mark);
1478+void i915_dump_lru(struct drm_device *dev, const char *where);
1479
1480 /* i915_suspend.c */
1481 extern int i915_save_state(struct drm_device *dev);
1482@@ -347,6 +591,7 @@ extern void opregion_enable_asle(struct drm_device *dev);
1483 */
1484 #define READ_HWSP(dev_priv, reg) (((volatile u32*)(dev_priv->hw_status_page))[reg])
1485 #define READ_BREADCRUMB(dev_priv) READ_HWSP(dev_priv, 5)
1486+#define I915_GEM_HWS_INDEX 0x10
1487
1488 extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
1489
1490diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
1491new file mode 100644
1492index 0000000..90ae8a0
1493--- /dev/null
1494+++ b/drivers/gpu/drm/i915/i915_gem.c
1495@@ -0,0 +1,2497 @@
1496+/*
1497+ * Copyright © 2008 Intel Corporation
1498+ *
1499+ * Permission is hereby granted, free of charge, to any person obtaining a
1500+ * copy of this software and associated documentation files (the "Software"),
1501+ * to deal in the Software without restriction, including without limitation
1502+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
1503+ * and/or sell copies of the Software, and to permit persons to whom the
1504+ * Software is furnished to do so, subject to the following conditions:
1505+ *
1506+ * The above copyright notice and this permission notice (including the next
1507+ * paragraph) shall be included in all copies or substantial portions of the
1508+ * Software.
1509+ *
1510+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1511+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1512+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
1513+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1514+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
1515+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
1516+ * IN THE SOFTWARE.
1517+ *
1518+ * Authors:
1519+ * Eric Anholt <eric@anholt.net>
1520+ *
1521+ */
1522+
1523+#include "drmP.h"
1524+#include "drm.h"
1525+#include "i915_drm.h"
1526+#include "i915_drv.h"
1527+#include <linux/swap.h>
1528+
1529+static int
1530+i915_gem_object_set_domain(struct drm_gem_object *obj,
1531+ uint32_t read_domains,
1532+ uint32_t write_domain);
1533+static int
1534+i915_gem_object_set_domain_range(struct drm_gem_object *obj,
1535+ uint64_t offset,
1536+ uint64_t size,
1537+ uint32_t read_domains,
1538+ uint32_t write_domain);
1539+static int
1540+i915_gem_set_domain(struct drm_gem_object *obj,
1541+ struct drm_file *file_priv,
1542+ uint32_t read_domains,
1543+ uint32_t write_domain);
1544+static int i915_gem_object_get_page_list(struct drm_gem_object *obj);
1545+static void i915_gem_object_free_page_list(struct drm_gem_object *obj);
1546+static int i915_gem_object_wait_rendering(struct drm_gem_object *obj);
1547+
1548+int
1549+i915_gem_init_ioctl(struct drm_device *dev, void *data,
1550+ struct drm_file *file_priv)
1551+{
1552+ drm_i915_private_t *dev_priv = dev->dev_private;
1553+ struct drm_i915_gem_init *args = data;
1554+
1555+ mutex_lock(&dev->struct_mutex);
1556+
1557+ if (args->gtt_start >= args->gtt_end ||
1558+ (args->gtt_start & (PAGE_SIZE - 1)) != 0 ||
1559+ (args->gtt_end & (PAGE_SIZE - 1)) != 0) {
1560+ mutex_unlock(&dev->struct_mutex);
1561+ return -EINVAL;
1562+ }
1563+
1564+ drm_mm_init(&dev_priv->mm.gtt_space, args->gtt_start,
1565+ args->gtt_end - args->gtt_start);
1566+
1567+ dev->gtt_total = (uint32_t) (args->gtt_end - args->gtt_start);
1568+
1569+ mutex_unlock(&dev->struct_mutex);
1570+
1571+ return 0;
1572+}
1573+
1574+
1575+/**
1576+ * Creates a new mm object and returns a handle to it.
1577+ */
1578+int
1579+i915_gem_create_ioctl(struct drm_device *dev, void *data,
1580+ struct drm_file *file_priv)
1581+{
1582+ struct drm_i915_gem_create *args = data;
1583+ struct drm_gem_object *obj;
1584+ int handle, ret;
1585+
1586+ args->size = roundup(args->size, PAGE_SIZE);
1587+
1588+ /* Allocate the new object */
1589+ obj = drm_gem_object_alloc(dev, args->size);
1590+ if (obj == NULL)
1591+ return -ENOMEM;
1592+
1593+ ret = drm_gem_handle_create(file_priv, obj, &handle);
1594+ mutex_lock(&dev->struct_mutex);
1595+ drm_gem_object_handle_unreference(obj);
1596+ mutex_unlock(&dev->struct_mutex);
1597+
1598+ if (ret)
1599+ return ret;
1600+
1601+ args->handle = handle;
1602+
1603+ return 0;
1604+}
1605+
1606+/**
1607+ * Reads data from the object referenced by handle.
1608+ *
1609+ * On error, the contents of *data are undefined.
1610+ */
1611+int
1612+i915_gem_pread_ioctl(struct drm_device *dev, void *data,
1613+ struct drm_file *file_priv)
1614+{
1615+ struct drm_i915_gem_pread *args = data;
1616+ struct drm_gem_object *obj;
1617+ struct drm_i915_gem_object *obj_priv;
1618+ ssize_t read;
1619+ loff_t offset;
1620+ int ret;
1621+
1622+ obj = drm_gem_object_lookup(dev, file_priv, args->handle);
1623+ if (obj == NULL)
1624+ return -EBADF;
1625+ obj_priv = obj->driver_private;
1626+
1627+ /* Bounds check source.
1628+ *
1629+ * XXX: This could use review for overflow issues...
1630+ */
1631+ if (args->offset > obj->size || args->size > obj->size ||
1632+ args->offset + args->size > obj->size) {
1633+ drm_gem_object_unreference(obj);
1634+ return -EINVAL;
1635+ }
1636+
1637+ mutex_lock(&dev->struct_mutex);
1638+
1639+ ret = i915_gem_object_set_domain_range(obj, args->offset, args->size,
1640+ I915_GEM_DOMAIN_CPU, 0);
1641+ if (ret != 0) {
1642+ drm_gem_object_unreference(obj);
1643+ mutex_unlock(&dev->struct_mutex);
1644+ }
1645+
1646+ offset = args->offset;
1647+
1648+ read = vfs_read(obj->filp, (char __user *)(uintptr_t)args->data_ptr,
1649+ args->size, &offset);
1650+ if (read != args->size) {
1651+ drm_gem_object_unreference(obj);
1652+ mutex_unlock(&dev->struct_mutex);
1653+ if (read < 0)
1654+ return read;
1655+ else
1656+ return -EINVAL;
1657+ }
1658+
1659+ drm_gem_object_unreference(obj);
1660+ mutex_unlock(&dev->struct_mutex);
1661+
1662+ return 0;
1663+}
1664+
1665+static int
1666+i915_gem_gtt_pwrite(struct drm_device *dev, struct drm_gem_object *obj,
1667+ struct drm_i915_gem_pwrite *args,
1668+ struct drm_file *file_priv)
1669+{
1670+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
1671+ ssize_t remain;
1672+ loff_t offset;
1673+ char __user *user_data;
1674+ char *vaddr;
1675+ int i, o, l;
1676+ int ret = 0;
1677+ unsigned long pfn;
1678+ unsigned long unwritten;
1679+
1680+ user_data = (char __user *) (uintptr_t) args->data_ptr;
1681+ remain = args->size;
1682+ if (!access_ok(VERIFY_READ, user_data, remain))
1683+ return -EFAULT;
1684+
1685+
1686+ mutex_lock(&dev->struct_mutex);
1687+ ret = i915_gem_object_pin(obj, 0);
1688+ if (ret) {
1689+ mutex_unlock(&dev->struct_mutex);
1690+ return ret;
1691+ }
1692+ ret = i915_gem_set_domain(obj, file_priv,
1693+ I915_GEM_DOMAIN_GTT, I915_GEM_DOMAIN_GTT);
1694+ if (ret)
1695+ goto fail;
1696+
1697+ obj_priv = obj->driver_private;
1698+ offset = obj_priv->gtt_offset + args->offset;
1699+ obj_priv->dirty = 1;
1700+
1701+ while (remain > 0) {
1702+ /* Operation in this page
1703+ *
1704+ * i = page number
1705+ * o = offset within page
1706+ * l = bytes to copy
1707+ */
1708+ i = offset >> PAGE_SHIFT;
1709+ o = offset & (PAGE_SIZE-1);
1710+ l = remain;
1711+ if ((o + l) > PAGE_SIZE)
1712+ l = PAGE_SIZE - o;
1713+
1714+ pfn = (dev->agp->base >> PAGE_SHIFT) + i;
1715+
1716+#ifdef CONFIG_HIGHMEM
1717+ /* kmap_atomic can't map IO pages on non-HIGHMEM kernels
1718+ */
1719+ vaddr = kmap_atomic_pfn(pfn, KM_USER0);
1720+#if WATCH_PWRITE
1721+ DRM_INFO("pwrite i %d o %d l %d pfn %ld vaddr %p\n",
1722+ i, o, l, pfn, vaddr);
1723+#endif
1724+ unwritten = __copy_from_user_inatomic_nocache(vaddr + o,
1725+ user_data, l);
1726+ kunmap_atomic(vaddr, KM_USER0);
1727+
1728+ if (unwritten)
1729+#endif /* CONFIG_HIGHMEM */
1730+ {
1731+ vaddr = ioremap(pfn << PAGE_SHIFT, PAGE_SIZE);
1732+#if WATCH_PWRITE
1733+ DRM_INFO("pwrite slow i %d o %d l %d "
1734+ "pfn %ld vaddr %p\n",
1735+ i, o, l, pfn, vaddr);
1736+#endif
1737+ if (vaddr == NULL) {
1738+ ret = -EFAULT;
1739+ goto fail;
1740+ }
1741+ unwritten = __copy_from_user(vaddr + o, user_data, l);
1742+#if WATCH_PWRITE
1743+ DRM_INFO("unwritten %ld\n", unwritten);
1744+#endif
1745+ iounmap(vaddr);
1746+ if (unwritten) {
1747+ ret = -EFAULT;
1748+ goto fail;
1749+ }
1750+ }
1751+
1752+ remain -= l;
1753+ user_data += l;
1754+ offset += l;
1755+ }
1756+#if WATCH_PWRITE && 1
1757+ i915_gem_clflush_object(obj);
1758+ i915_gem_dump_object(obj, args->offset + args->size, __func__, ~0);
1759+ i915_gem_clflush_object(obj);
1760+#endif
1761+
1762+fail:
1763+ i915_gem_object_unpin(obj);
1764+ mutex_unlock(&dev->struct_mutex);
1765+
1766+ return ret;
1767+}
1768+
1769+int
1770+i915_gem_shmem_pwrite(struct drm_device *dev, struct drm_gem_object *obj,
1771+ struct drm_i915_gem_pwrite *args,
1772+ struct drm_file *file_priv)
1773+{
1774+ int ret;
1775+ loff_t offset;
1776+ ssize_t written;
1777+
1778+ mutex_lock(&dev->struct_mutex);
1779+
1780+ ret = i915_gem_set_domain(obj, file_priv,
1781+ I915_GEM_DOMAIN_CPU, I915_GEM_DOMAIN_CPU);
1782+ if (ret) {
1783+ mutex_unlock(&dev->struct_mutex);
1784+ return ret;
1785+ }
1786+
1787+ offset = args->offset;
1788+
1789+ written = vfs_write(obj->filp,
1790+ (char __user *)(uintptr_t) args->data_ptr,
1791+ args->size, &offset);
1792+ if (written != args->size) {
1793+ mutex_unlock(&dev->struct_mutex);
1794+ if (written < 0)
1795+ return written;
1796+ else
1797+ return -EINVAL;
1798+ }
1799+
1800+ mutex_unlock(&dev->struct_mutex);
1801+
1802+ return 0;
1803+}
1804+
1805+/**
1806+ * Writes data to the object referenced by handle.
1807+ *
1808+ * On error, the contents of the buffer that were to be modified are undefined.
1809+ */
1810+int
1811+i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
1812+ struct drm_file *file_priv)
1813+{
1814+ struct drm_i915_gem_pwrite *args = data;
1815+ struct drm_gem_object *obj;
1816+ struct drm_i915_gem_object *obj_priv;
1817+ int ret = 0;
1818+
1819+ obj = drm_gem_object_lookup(dev, file_priv, args->handle);
1820+ if (obj == NULL)
1821+ return -EBADF;
1822+ obj_priv = obj->driver_private;
1823+
1824+ /* Bounds check destination.
1825+ *
1826+ * XXX: This could use review for overflow issues...
1827+ */
1828+ if (args->offset > obj->size || args->size > obj->size ||
1829+ args->offset + args->size > obj->size) {
1830+ drm_gem_object_unreference(obj);
1831+ return -EINVAL;
1832+ }
1833+
1834+ /* We can only do the GTT pwrite on untiled buffers, as otherwise
1835+ * it would end up going through the fenced access, and we'll get
1836+ * different detiling behavior between reading and writing.
1837+ * pread/pwrite currently are reading and writing from the CPU
1838+ * perspective, requiring manual detiling by the client.
1839+ */
1840+ if (obj_priv->tiling_mode == I915_TILING_NONE &&
1841+ dev->gtt_total != 0)
1842+ ret = i915_gem_gtt_pwrite(dev, obj, args, file_priv);
1843+ else
1844+ ret = i915_gem_shmem_pwrite(dev, obj, args, file_priv);
1845+
1846+#if WATCH_PWRITE
1847+ if (ret)
1848+ DRM_INFO("pwrite failed %d\n", ret);
1849+#endif
1850+
1851+ drm_gem_object_unreference(obj);
1852+
1853+ return ret;
1854+}
1855+
1856+/**
1857+ * Called when user space prepares to use an object
1858+ */
1859+int
1860+i915_gem_set_domain_ioctl(struct drm_device *dev, void *data,
1861+ struct drm_file *file_priv)
1862+{
1863+ struct drm_i915_gem_set_domain *args = data;
1864+ struct drm_gem_object *obj;
1865+ int ret;
1866+
1867+ if (!(dev->driver->driver_features & DRIVER_GEM))
1868+ return -ENODEV;
1869+
1870+ obj = drm_gem_object_lookup(dev, file_priv, args->handle);
1871+ if (obj == NULL)
1872+ return -EBADF;
1873+
1874+ mutex_lock(&dev->struct_mutex);
1875+#if WATCH_BUF
1876+ DRM_INFO("set_domain_ioctl %p(%d), %08x %08x\n",
1877+ obj, obj->size, args->read_domains, args->write_domain);
1878+#endif
1879+ ret = i915_gem_set_domain(obj, file_priv,
1880+ args->read_domains, args->write_domain);
1881+ drm_gem_object_unreference(obj);
1882+ mutex_unlock(&dev->struct_mutex);
1883+ return ret;
1884+}
1885+
1886+/**
1887+ * Called when user space has done writes to this buffer
1888+ */
1889+int
1890+i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data,
1891+ struct drm_file *file_priv)
1892+{
1893+ struct drm_i915_gem_sw_finish *args = data;
1894+ struct drm_gem_object *obj;
1895+ struct drm_i915_gem_object *obj_priv;
1896+ int ret = 0;
1897+
1898+ if (!(dev->driver->driver_features & DRIVER_GEM))
1899+ return -ENODEV;
1900+
1901+ mutex_lock(&dev->struct_mutex);
1902+ obj = drm_gem_object_lookup(dev, file_priv, args->handle);
1903+ if (obj == NULL) {
1904+ mutex_unlock(&dev->struct_mutex);
1905+ return -EBADF;
1906+ }
1907+
1908+#if WATCH_BUF
1909+ DRM_INFO("%s: sw_finish %d (%p %d)\n",
1910+ __func__, args->handle, obj, obj->size);
1911+#endif
1912+ obj_priv = obj->driver_private;
1913+
1914+ /* Pinned buffers may be scanout, so flush the cache */
1915+ if ((obj->write_domain & I915_GEM_DOMAIN_CPU) && obj_priv->pin_count) {
1916+ i915_gem_clflush_object(obj);
1917+ drm_agp_chipset_flush(dev);
1918+ }
1919+ drm_gem_object_unreference(obj);
1920+ mutex_unlock(&dev->struct_mutex);
1921+ return ret;
1922+}
1923+
1924+/**
1925+ * Maps the contents of an object, returning the address it is mapped
1926+ * into.
1927+ *
1928+ * While the mapping holds a reference on the contents of the object, it doesn't
1929+ * imply a ref on the object itself.
1930+ */
1931+int
1932+i915_gem_mmap_ioctl(struct drm_device *dev, void *data,
1933+ struct drm_file *file_priv)
1934+{
1935+ struct drm_i915_gem_mmap *args = data;
1936+ struct drm_gem_object *obj;
1937+ loff_t offset;
1938+ unsigned long addr;
1939+
1940+ if (!(dev->driver->driver_features & DRIVER_GEM))
1941+ return -ENODEV;
1942+
1943+ obj = drm_gem_object_lookup(dev, file_priv, args->handle);
1944+ if (obj == NULL)
1945+ return -EBADF;
1946+
1947+ offset = args->offset;
1948+
1949+ down_write(&current->mm->mmap_sem);
1950+ addr = do_mmap(obj->filp, 0, args->size,
1951+ PROT_READ | PROT_WRITE, MAP_SHARED,
1952+ args->offset);
1953+ up_write(&current->mm->mmap_sem);
1954+ mutex_lock(&dev->struct_mutex);
1955+ drm_gem_object_unreference(obj);
1956+ mutex_unlock(&dev->struct_mutex);
1957+ if (IS_ERR((void *)addr))
1958+ return addr;
1959+
1960+ args->addr_ptr = (uint64_t) addr;
1961+
1962+ return 0;
1963+}
1964+
1965+static void
1966+i915_gem_object_free_page_list(struct drm_gem_object *obj)
1967+{
1968+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
1969+ int page_count = obj->size / PAGE_SIZE;
1970+ int i;
1971+
1972+ if (obj_priv->page_list == NULL)
1973+ return;
1974+
1975+
1976+ for (i = 0; i < page_count; i++)
1977+ if (obj_priv->page_list[i] != NULL) {
1978+ if (obj_priv->dirty)
1979+ set_page_dirty(obj_priv->page_list[i]);
1980+ mark_page_accessed(obj_priv->page_list[i]);
1981+ page_cache_release(obj_priv->page_list[i]);
1982+ }
1983+ obj_priv->dirty = 0;
1984+
1985+ drm_free(obj_priv->page_list,
1986+ page_count * sizeof(struct page *),
1987+ DRM_MEM_DRIVER);
1988+ obj_priv->page_list = NULL;
1989+}
1990+
1991+static void
1992+i915_gem_object_move_to_active(struct drm_gem_object *obj)
1993+{
1994+ struct drm_device *dev = obj->dev;
1995+ drm_i915_private_t *dev_priv = dev->dev_private;
1996+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
1997+
1998+ /* Add a reference if we're newly entering the active list. */
1999+ if (!obj_priv->active) {
2000+ drm_gem_object_reference(obj);
2001+ obj_priv->active = 1;
2002+ }
2003+ /* Move from whatever list we were on to the tail of execution. */
2004+ list_move_tail(&obj_priv->list,
2005+ &dev_priv->mm.active_list);
2006+}
2007+
2008+
2009+static void
2010+i915_gem_object_move_to_inactive(struct drm_gem_object *obj)
2011+{
2012+ struct drm_device *dev = obj->dev;
2013+ drm_i915_private_t *dev_priv = dev->dev_private;
2014+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
2015+
2016+ i915_verify_inactive(dev, __FILE__, __LINE__);
2017+ if (obj_priv->pin_count != 0)
2018+ list_del_init(&obj_priv->list);
2019+ else
2020+ list_move_tail(&obj_priv->list, &dev_priv->mm.inactive_list);
2021+
2022+ if (obj_priv->active) {
2023+ obj_priv->active = 0;
2024+ drm_gem_object_unreference(obj);
2025+ }
2026+ i915_verify_inactive(dev, __FILE__, __LINE__);
2027+}
2028+
2029+/**
2030+ * Creates a new sequence number, emitting a write of it to the status page
2031+ * plus an interrupt, which will trigger i915_user_interrupt_handler.
2032+ *
2033+ * Must be called with struct_lock held.
2034+ *
2035+ * Returned sequence numbers are nonzero on success.
2036+ */
2037+static uint32_t
2038+i915_add_request(struct drm_device *dev, uint32_t flush_domains)
2039+{
2040+ drm_i915_private_t *dev_priv = dev->dev_private;
2041+ struct drm_i915_gem_request *request;
2042+ uint32_t seqno;
2043+ int was_empty;
2044+ RING_LOCALS;
2045+
2046+ request = drm_calloc(1, sizeof(*request), DRM_MEM_DRIVER);
2047+ if (request == NULL)
2048+ return 0;
2049+
2050+ /* Grab the seqno we're going to make this request be, and bump the
2051+ * next (skipping 0 so it can be the reserved no-seqno value).
2052+ */
2053+ seqno = dev_priv->mm.next_gem_seqno;
2054+ dev_priv->mm.next_gem_seqno++;
2055+ if (dev_priv->mm.next_gem_seqno == 0)
2056+ dev_priv->mm.next_gem_seqno++;
2057+
2058+ BEGIN_LP_RING(4);
2059+ OUT_RING(MI_STORE_DWORD_INDEX);
2060+ OUT_RING(I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
2061+ OUT_RING(seqno);
2062+
2063+ OUT_RING(MI_USER_INTERRUPT);
2064+ ADVANCE_LP_RING();
2065+
2066+ DRM_DEBUG("%d\n", seqno);
2067+
2068+ request->seqno = seqno;
2069+ request->emitted_jiffies = jiffies;
2070+ request->flush_domains = flush_domains;
2071+ was_empty = list_empty(&dev_priv->mm.request_list);
2072+ list_add_tail(&request->list, &dev_priv->mm.request_list);
2073+
2074+ if (was_empty)
2075+ schedule_delayed_work(&dev_priv->mm.retire_work, HZ);
2076+ return seqno;
2077+}
2078+
2079+/**
2080+ * Command execution barrier
2081+ *
2082+ * Ensures that all commands in the ring are finished
2083+ * before signalling the CPU
2084+ */
2085+uint32_t
2086+i915_retire_commands(struct drm_device *dev)
2087+{
2088+ drm_i915_private_t *dev_priv = dev->dev_private;
2089+ uint32_t cmd = MI_FLUSH | MI_NO_WRITE_FLUSH;
2090+ uint32_t flush_domains = 0;
2091+ RING_LOCALS;
2092+
2093+ /* The sampler always gets flushed on i965 (sigh) */
2094+ if (IS_I965G(dev))
2095+ flush_domains |= I915_GEM_DOMAIN_SAMPLER;
2096+ BEGIN_LP_RING(2);
2097+ OUT_RING(cmd);
2098+ OUT_RING(0); /* noop */
2099+ ADVANCE_LP_RING();
2100+ return flush_domains;
2101+}
2102+
2103+/**
2104+ * Moves buffers associated only with the given active seqno from the active
2105+ * to inactive list, potentially freeing them.
2106+ */
2107+static void
2108+i915_gem_retire_request(struct drm_device *dev,
2109+ struct drm_i915_gem_request *request)
2110+{
2111+ drm_i915_private_t *dev_priv = dev->dev_private;
2112+
2113+ /* Move any buffers on the active list that are no longer referenced
2114+ * by the ringbuffer to the flushing/inactive lists as appropriate.
2115+ */
2116+ while (!list_empty(&dev_priv->mm.active_list)) {
2117+ struct drm_gem_object *obj;
2118+ struct drm_i915_gem_object *obj_priv;
2119+
2120+ obj_priv = list_first_entry(&dev_priv->mm.active_list,
2121+ struct drm_i915_gem_object,
2122+ list);
2123+ obj = obj_priv->obj;
2124+
2125+ /* If the seqno being retired doesn't match the oldest in the
2126+ * list, then the oldest in the list must still be newer than
2127+ * this seqno.
2128+ */
2129+ if (obj_priv->last_rendering_seqno != request->seqno)
2130+ return;
2131+#if WATCH_LRU
2132+ DRM_INFO("%s: retire %d moves to inactive list %p\n",
2133+ __func__, request->seqno, obj);
2134+#endif
2135+
2136+ if (obj->write_domain != 0) {
2137+ list_move_tail(&obj_priv->list,
2138+ &dev_priv->mm.flushing_list);
2139+ } else {
2140+ i915_gem_object_move_to_inactive(obj);
2141+ }
2142+ }
2143+
2144+ if (request->flush_domains != 0) {
2145+ struct drm_i915_gem_object *obj_priv, *next;
2146+
2147+ /* Clear the write domain and activity from any buffers
2148+ * that are just waiting for a flush matching the one retired.
2149+ */
2150+ list_for_each_entry_safe(obj_priv, next,
2151+ &dev_priv->mm.flushing_list, list) {
2152+ struct drm_gem_object *obj = obj_priv->obj;
2153+
2154+ if (obj->write_domain & request->flush_domains) {
2155+ obj->write_domain = 0;
2156+ i915_gem_object_move_to_inactive(obj);
2157+ }
2158+ }
2159+
2160+ }
2161+}
2162+
2163+/**
2164+ * Returns true if seq1 is later than seq2.
2165+ */
2166+static int
2167+i915_seqno_passed(uint32_t seq1, uint32_t seq2)
2168+{
2169+ return (int32_t)(seq1 - seq2) >= 0;
2170+}
2171+
2172+uint32_t
2173+i915_get_gem_seqno(struct drm_device *dev)
2174+{
2175+ drm_i915_private_t *dev_priv = dev->dev_private;
2176+
2177+ return READ_HWSP(dev_priv, I915_GEM_HWS_INDEX);
2178+}
2179+
2180+/**
2181+ * This function clears the request list as sequence numbers are passed.
2182+ */
2183+void
2184+i915_gem_retire_requests(struct drm_device *dev)
2185+{
2186+ drm_i915_private_t *dev_priv = dev->dev_private;
2187+ uint32_t seqno;
2188+
2189+ seqno = i915_get_gem_seqno(dev);
2190+
2191+ while (!list_empty(&dev_priv->mm.request_list)) {
2192+ struct drm_i915_gem_request *request;
2193+ uint32_t retiring_seqno;
2194+
2195+ request = list_first_entry(&dev_priv->mm.request_list,
2196+ struct drm_i915_gem_request,
2197+ list);
2198+ retiring_seqno = request->seqno;
2199+
2200+ if (i915_seqno_passed(seqno, retiring_seqno) ||
2201+ dev_priv->mm.wedged) {
2202+ i915_gem_retire_request(dev, request);
2203+
2204+ list_del(&request->list);
2205+ drm_free(request, sizeof(*request), DRM_MEM_DRIVER);
2206+ } else
2207+ break;
2208+ }
2209+}
2210+
2211+void
2212+i915_gem_retire_work_handler(struct work_struct *work)
2213+{
2214+ drm_i915_private_t *dev_priv;
2215+ struct drm_device *dev;
2216+
2217+ dev_priv = container_of(work, drm_i915_private_t,
2218+ mm.retire_work.work);
2219+ dev = dev_priv->dev;
2220+
2221+ mutex_lock(&dev->struct_mutex);
2222+ i915_gem_retire_requests(dev);
2223+ if (!list_empty(&dev_priv->mm.request_list))
2224+ schedule_delayed_work(&dev_priv->mm.retire_work, HZ);
2225+ mutex_unlock(&dev->struct_mutex);
2226+}
2227+
2228+/**
2229+ * Waits for a sequence number to be signaled, and cleans up the
2230+ * request and object lists appropriately for that event.
2231+ */
2232+int
2233+i915_wait_request(struct drm_device *dev, uint32_t seqno)
2234+{
2235+ drm_i915_private_t *dev_priv = dev->dev_private;
2236+ int ret = 0;
2237+
2238+ BUG_ON(seqno == 0);
2239+
2240+ if (!i915_seqno_passed(i915_get_gem_seqno(dev), seqno)) {
2241+ dev_priv->mm.waiting_gem_seqno = seqno;
2242+ i915_user_irq_get(dev);
2243+ ret = wait_event_interruptible(dev_priv->irq_queue,
2244+ i915_seqno_passed(i915_get_gem_seqno(dev),
2245+ seqno) ||
2246+ dev_priv->mm.wedged);
2247+ i915_user_irq_put(dev);
2248+ dev_priv->mm.waiting_gem_seqno = 0;
2249+ }
2250+ if (dev_priv->mm.wedged)
2251+ ret = -EIO;
2252+
2253+ if (ret && ret != -ERESTARTSYS)
2254+ DRM_ERROR("%s returns %d (awaiting %d at %d)\n",
2255+ __func__, ret, seqno, i915_get_gem_seqno(dev));
2256+
2257+ /* Directly dispatch request retiring. While we have the work queue
2258+ * to handle this, the waiter on a request often wants an associated
2259+ * buffer to have made it to the inactive list, and we would need
2260+ * a separate wait queue to handle that.
2261+ */
2262+ if (ret == 0)
2263+ i915_gem_retire_requests(dev);
2264+
2265+ return ret;
2266+}
2267+
2268+static void
2269+i915_gem_flush(struct drm_device *dev,
2270+ uint32_t invalidate_domains,
2271+ uint32_t flush_domains)
2272+{
2273+ drm_i915_private_t *dev_priv = dev->dev_private;
2274+ uint32_t cmd;
2275+ RING_LOCALS;
2276+
2277+#if WATCH_EXEC
2278+ DRM_INFO("%s: invalidate %08x flush %08x\n", __func__,
2279+ invalidate_domains, flush_domains);
2280+#endif
2281+
2282+ if (flush_domains & I915_GEM_DOMAIN_CPU)
2283+ drm_agp_chipset_flush(dev);
2284+
2285+ if ((invalidate_domains | flush_domains) & ~(I915_GEM_DOMAIN_CPU |
2286+ I915_GEM_DOMAIN_GTT)) {
2287+ /*
2288+ * read/write caches:
2289+ *
2290+ * I915_GEM_DOMAIN_RENDER is always invalidated, but is
2291+ * only flushed if MI_NO_WRITE_FLUSH is unset. On 965, it is
2292+ * also flushed at 2d versus 3d pipeline switches.
2293+ *
2294+ * read-only caches:
2295+ *
2296+ * I915_GEM_DOMAIN_SAMPLER is flushed on pre-965 if
2297+ * MI_READ_FLUSH is set, and is always flushed on 965.
2298+ *
2299+ * I915_GEM_DOMAIN_COMMAND may not exist?
2300+ *
2301+ * I915_GEM_DOMAIN_INSTRUCTION, which exists on 965, is
2302+ * invalidated when MI_EXE_FLUSH is set.
2303+ *
2304+ * I915_GEM_DOMAIN_VERTEX, which exists on 965, is
2305+ * invalidated with every MI_FLUSH.
2306+ *
2307+ * TLBs:
2308+ *
2309+ * On 965, TLBs associated with I915_GEM_DOMAIN_COMMAND
2310+ * and I915_GEM_DOMAIN_CPU in are invalidated at PTE write and
2311+ * I915_GEM_DOMAIN_RENDER and I915_GEM_DOMAIN_SAMPLER
2312+ * are flushed at any MI_FLUSH.
2313+ */
2314+
2315+ cmd = MI_FLUSH | MI_NO_WRITE_FLUSH;
2316+ if ((invalidate_domains|flush_domains) &
2317+ I915_GEM_DOMAIN_RENDER)
2318+ cmd &= ~MI_NO_WRITE_FLUSH;
2319+ if (!IS_I965G(dev)) {
2320+ /*
2321+ * On the 965, the sampler cache always gets flushed
2322+ * and this bit is reserved.
2323+ */
2324+ if (invalidate_domains & I915_GEM_DOMAIN_SAMPLER)
2325+ cmd |= MI_READ_FLUSH;
2326+ }
2327+ if (invalidate_domains & I915_GEM_DOMAIN_INSTRUCTION)
2328+ cmd |= MI_EXE_FLUSH;
2329+
2330+#if WATCH_EXEC
2331+ DRM_INFO("%s: queue flush %08x to ring\n", __func__, cmd);
2332+#endif
2333+ BEGIN_LP_RING(2);
2334+ OUT_RING(cmd);
2335+ OUT_RING(0); /* noop */
2336+ ADVANCE_LP_RING();
2337+ }
2338+}
2339+
2340+/**
2341+ * Ensures that all rendering to the object has completed and the object is
2342+ * safe to unbind from the GTT or access from the CPU.
2343+ */
2344+static int
2345+i915_gem_object_wait_rendering(struct drm_gem_object *obj)
2346+{
2347+ struct drm_device *dev = obj->dev;
2348+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
2349+ int ret;
2350+
2351+ /* If there are writes queued to the buffer, flush and
2352+ * create a new seqno to wait for.
2353+ */
2354+ if (obj->write_domain & ~(I915_GEM_DOMAIN_CPU|I915_GEM_DOMAIN_GTT)) {
2355+ uint32_t write_domain = obj->write_domain;
2356+#if WATCH_BUF
2357+ DRM_INFO("%s: flushing object %p from write domain %08x\n",
2358+ __func__, obj, write_domain);
2359+#endif
2360+ i915_gem_flush(dev, 0, write_domain);
2361+
2362+ i915_gem_object_move_to_active(obj);
2363+ obj_priv->last_rendering_seqno = i915_add_request(dev,
2364+ write_domain);
2365+ BUG_ON(obj_priv->last_rendering_seqno == 0);
2366+#if WATCH_LRU
2367+ DRM_INFO("%s: flush moves to exec list %p\n", __func__, obj);
2368+#endif
2369+ }
2370+
2371+ /* If there is rendering queued on the buffer being evicted, wait for
2372+ * it.
2373+ */
2374+ if (obj_priv->active) {
2375+#if WATCH_BUF
2376+ DRM_INFO("%s: object %p wait for seqno %08x\n",
2377+ __func__, obj, obj_priv->last_rendering_seqno);
2378+#endif
2379+ ret = i915_wait_request(dev, obj_priv->last_rendering_seqno);
2380+ if (ret != 0)
2381+ return ret;
2382+ }
2383+
2384+ return 0;
2385+}
2386+
2387+/**
2388+ * Unbinds an object from the GTT aperture.
2389+ */
2390+static int
2391+i915_gem_object_unbind(struct drm_gem_object *obj)
2392+{
2393+ struct drm_device *dev = obj->dev;
2394+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
2395+ int ret = 0;
2396+
2397+#if WATCH_BUF
2398+ DRM_INFO("%s:%d %p\n", __func__, __LINE__, obj);
2399+ DRM_INFO("gtt_space %p\n", obj_priv->gtt_space);
2400+#endif
2401+ if (obj_priv->gtt_space == NULL)
2402+ return 0;
2403+
2404+ if (obj_priv->pin_count != 0) {
2405+ DRM_ERROR("Attempting to unbind pinned buffer\n");
2406+ return -EINVAL;
2407+ }
2408+
2409+ /* Wait for any rendering to complete
2410+ */
2411+ ret = i915_gem_object_wait_rendering(obj);
2412+ if (ret) {
2413+ DRM_ERROR("wait_rendering failed: %d\n", ret);
2414+ return ret;
2415+ }
2416+
2417+ /* Move the object to the CPU domain to ensure that
2418+ * any possible CPU writes while it's not in the GTT
2419+ * are flushed when we go to remap it. This will
2420+ * also ensure that all pending GPU writes are finished
2421+ * before we unbind.
2422+ */
2423+ ret = i915_gem_object_set_domain(obj, I915_GEM_DOMAIN_CPU,
2424+ I915_GEM_DOMAIN_CPU);
2425+ if (ret) {
2426+ DRM_ERROR("set_domain failed: %d\n", ret);
2427+ return ret;
2428+ }
2429+
2430+ if (obj_priv->agp_mem != NULL) {
2431+ drm_unbind_agp(obj_priv->agp_mem);
2432+ drm_free_agp(obj_priv->agp_mem, obj->size / PAGE_SIZE);
2433+ obj_priv->agp_mem = NULL;
2434+ }
2435+
2436+ BUG_ON(obj_priv->active);
2437+
2438+ i915_gem_object_free_page_list(obj);
2439+
2440+ if (obj_priv->gtt_space) {
2441+ atomic_dec(&dev->gtt_count);
2442+ atomic_sub(obj->size, &dev->gtt_memory);
2443+
2444+ drm_mm_put_block(obj_priv->gtt_space);
2445+ obj_priv->gtt_space = NULL;
2446+ }
2447+
2448+ /* Remove ourselves from the LRU list if present. */
2449+ if (!list_empty(&obj_priv->list))
2450+ list_del_init(&obj_priv->list);
2451+
2452+ return 0;
2453+}
2454+
2455+static int
2456+i915_gem_evict_something(struct drm_device *dev)
2457+{
2458+ drm_i915_private_t *dev_priv = dev->dev_private;
2459+ struct drm_gem_object *obj;
2460+ struct drm_i915_gem_object *obj_priv;
2461+ int ret = 0;
2462+
2463+ for (;;) {
2464+ /* If there's an inactive buffer available now, grab it
2465+ * and be done.
2466+ */
2467+ if (!list_empty(&dev_priv->mm.inactive_list)) {
2468+ obj_priv = list_first_entry(&dev_priv->mm.inactive_list,
2469+ struct drm_i915_gem_object,
2470+ list);
2471+ obj = obj_priv->obj;
2472+ BUG_ON(obj_priv->pin_count != 0);
2473+#if WATCH_LRU
2474+ DRM_INFO("%s: evicting %p\n", __func__, obj);
2475+#endif
2476+ BUG_ON(obj_priv->active);
2477+
2478+ /* Wait on the rendering and unbind the buffer. */
2479+ ret = i915_gem_object_unbind(obj);
2480+ break;
2481+ }
2482+
2483+ /* If we didn't get anything, but the ring is still processing
2484+ * things, wait for one of those things to finish and hopefully
2485+ * leave us a buffer to evict.
2486+ */
2487+ if (!list_empty(&dev_priv->mm.request_list)) {
2488+ struct drm_i915_gem_request *request;
2489+
2490+ request = list_first_entry(&dev_priv->mm.request_list,
2491+ struct drm_i915_gem_request,
2492+ list);
2493+
2494+ ret = i915_wait_request(dev, request->seqno);
2495+ if (ret)
2496+ break;
2497+
2498+ /* if waiting caused an object to become inactive,
2499+ * then loop around and wait for it. Otherwise, we
2500+ * assume that waiting freed and unbound something,
2501+ * so there should now be some space in the GTT
2502+ */
2503+ if (!list_empty(&dev_priv->mm.inactive_list))
2504+ continue;
2505+ break;
2506+ }
2507+
2508+ /* If we didn't have anything on the request list but there
2509+ * are buffers awaiting a flush, emit one and try again.
2510+ * When we wait on it, those buffers waiting for that flush
2511+ * will get moved to inactive.
2512+ */
2513+ if (!list_empty(&dev_priv->mm.flushing_list)) {
2514+ obj_priv = list_first_entry(&dev_priv->mm.flushing_list,
2515+ struct drm_i915_gem_object,
2516+ list);
2517+ obj = obj_priv->obj;
2518+
2519+ i915_gem_flush(dev,
2520+ obj->write_domain,
2521+ obj->write_domain);
2522+ i915_add_request(dev, obj->write_domain);
2523+
2524+ obj = NULL;
2525+ continue;
2526+ }
2527+
2528+ DRM_ERROR("inactive empty %d request empty %d "
2529+ "flushing empty %d\n",
2530+ list_empty(&dev_priv->mm.inactive_list),
2531+ list_empty(&dev_priv->mm.request_list),
2532+ list_empty(&dev_priv->mm.flushing_list));
2533+ /* If we didn't do any of the above, there's nothing to be done
2534+ * and we just can't fit it in.
2535+ */
2536+ return -ENOMEM;
2537+ }
2538+ return ret;
2539+}
2540+
2541+static int
2542+i915_gem_object_get_page_list(struct drm_gem_object *obj)
2543+{
2544+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
2545+ int page_count, i;
2546+ struct address_space *mapping;
2547+ struct inode *inode;
2548+ struct page *page;
2549+ int ret;
2550+
2551+ if (obj_priv->page_list)
2552+ return 0;
2553+
2554+ /* Get the list of pages out of our struct file. They'll be pinned
2555+ * at this point until we release them.
2556+ */
2557+ page_count = obj->size / PAGE_SIZE;
2558+ BUG_ON(obj_priv->page_list != NULL);
2559+ obj_priv->page_list = drm_calloc(page_count, sizeof(struct page *),
2560+ DRM_MEM_DRIVER);
2561+ if (obj_priv->page_list == NULL) {
2562+ DRM_ERROR("Faled to allocate page list\n");
2563+ return -ENOMEM;
2564+ }
2565+
2566+ inode = obj->filp->f_path.dentry->d_inode;
2567+ mapping = inode->i_mapping;
2568+ for (i = 0; i < page_count; i++) {
2569+ page = read_mapping_page(mapping, i, NULL);
2570+ if (IS_ERR(page)) {
2571+ ret = PTR_ERR(page);
2572+ DRM_ERROR("read_mapping_page failed: %d\n", ret);
2573+ i915_gem_object_free_page_list(obj);
2574+ return ret;
2575+ }
2576+ obj_priv->page_list[i] = page;
2577+ }
2578+ return 0;
2579+}
2580+
2581+/**
2582+ * Finds free space in the GTT aperture and binds the object there.
2583+ */
2584+static int
2585+i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment)
2586+{
2587+ struct drm_device *dev = obj->dev;
2588+ drm_i915_private_t *dev_priv = dev->dev_private;
2589+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
2590+ struct drm_mm_node *free_space;
2591+ int page_count, ret;
2592+
2593+ if (alignment == 0)
2594+ alignment = PAGE_SIZE;
2595+ if (alignment & (PAGE_SIZE - 1)) {
2596+ DRM_ERROR("Invalid object alignment requested %u\n", alignment);
2597+ return -EINVAL;
2598+ }
2599+
2600+ search_free:
2601+ free_space = drm_mm_search_free(&dev_priv->mm.gtt_space,
2602+ obj->size, alignment, 0);
2603+ if (free_space != NULL) {
2604+ obj_priv->gtt_space = drm_mm_get_block(free_space, obj->size,
2605+ alignment);
2606+ if (obj_priv->gtt_space != NULL) {
2607+ obj_priv->gtt_space->private = obj;
2608+ obj_priv->gtt_offset = obj_priv->gtt_space->start;
2609+ }
2610+ }
2611+ if (obj_priv->gtt_space == NULL) {
2612+ /* If the gtt is empty and we're still having trouble
2613+ * fitting our object in, we're out of memory.
2614+ */
2615+#if WATCH_LRU
2616+ DRM_INFO("%s: GTT full, evicting something\n", __func__);
2617+#endif
2618+ if (list_empty(&dev_priv->mm.inactive_list) &&
2619+ list_empty(&dev_priv->mm.flushing_list) &&
2620+ list_empty(&dev_priv->mm.active_list)) {
2621+ DRM_ERROR("GTT full, but LRU list empty\n");
2622+ return -ENOMEM;
2623+ }
2624+
2625+ ret = i915_gem_evict_something(dev);
2626+ if (ret != 0) {
2627+ DRM_ERROR("Failed to evict a buffer %d\n", ret);
2628+ return ret;
2629+ }
2630+ goto search_free;
2631+ }
2632+
2633+#if WATCH_BUF
2634+ DRM_INFO("Binding object of size %d at 0x%08x\n",
2635+ obj->size, obj_priv->gtt_offset);
2636+#endif
2637+ ret = i915_gem_object_get_page_list(obj);
2638+ if (ret) {
2639+ drm_mm_put_block(obj_priv->gtt_space);
2640+ obj_priv->gtt_space = NULL;
2641+ return ret;
2642+ }
2643+
2644+ page_count = obj->size / PAGE_SIZE;
2645+ /* Create an AGP memory structure pointing at our pages, and bind it
2646+ * into the GTT.
2647+ */
2648+ obj_priv->agp_mem = drm_agp_bind_pages(dev,
2649+ obj_priv->page_list,
2650+ page_count,
2651+ obj_priv->gtt_offset);
2652+ if (obj_priv->agp_mem == NULL) {
2653+ i915_gem_object_free_page_list(obj);
2654+ drm_mm_put_block(obj_priv->gtt_space);
2655+ obj_priv->gtt_space = NULL;
2656+ return -ENOMEM;
2657+ }
2658+ atomic_inc(&dev->gtt_count);
2659+ atomic_add(obj->size, &dev->gtt_memory);
2660+
2661+ /* Assert that the object is not currently in any GPU domain. As it
2662+ * wasn't in the GTT, there shouldn't be any way it could have been in
2663+ * a GPU cache
2664+ */
2665+ BUG_ON(obj->read_domains & ~(I915_GEM_DOMAIN_CPU|I915_GEM_DOMAIN_GTT));
2666+ BUG_ON(obj->write_domain & ~(I915_GEM_DOMAIN_CPU|I915_GEM_DOMAIN_GTT));
2667+
2668+ return 0;
2669+}
2670+
2671+void
2672+i915_gem_clflush_object(struct drm_gem_object *obj)
2673+{
2674+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
2675+
2676+ /* If we don't have a page list set up, then we're not pinned
2677+ * to GPU, and we can ignore the cache flush because it'll happen
2678+ * again at bind time.
2679+ */
2680+ if (obj_priv->page_list == NULL)
2681+ return;
2682+
2683+ drm_clflush_pages(obj_priv->page_list, obj->size / PAGE_SIZE);
2684+}
2685+
2686+/*
2687+ * Set the next domain for the specified object. This
2688+ * may not actually perform the necessary flushing/invaliding though,
2689+ * as that may want to be batched with other set_domain operations
2690+ *
2691+ * This is (we hope) the only really tricky part of gem. The goal
2692+ * is fairly simple -- track which caches hold bits of the object
2693+ * and make sure they remain coherent. A few concrete examples may
2694+ * help to explain how it works. For shorthand, we use the notation
2695+ * (read_domains, write_domain), e.g. (CPU, CPU) to indicate the
2696+ * a pair of read and write domain masks.
2697+ *
2698+ * Case 1: the batch buffer
2699+ *
2700+ * 1. Allocated
2701+ * 2. Written by CPU
2702+ * 3. Mapped to GTT
2703+ * 4. Read by GPU
2704+ * 5. Unmapped from GTT
2705+ * 6. Freed
2706+ *
2707+ * Let's take these a step at a time
2708+ *
2709+ * 1. Allocated
2710+ * Pages allocated from the kernel may still have
2711+ * cache contents, so we set them to (CPU, CPU) always.
2712+ * 2. Written by CPU (using pwrite)
2713+ * The pwrite function calls set_domain (CPU, CPU) and
2714+ * this function does nothing (as nothing changes)
2715+ * 3. Mapped by GTT
2716+ * This function asserts that the object is not
2717+ * currently in any GPU-based read or write domains
2718+ * 4. Read by GPU
2719+ * i915_gem_execbuffer calls set_domain (COMMAND, 0).
2720+ * As write_domain is zero, this function adds in the
2721+ * current read domains (CPU+COMMAND, 0).
2722+ * flush_domains is set to CPU.
2723+ * invalidate_domains is set to COMMAND
2724+ * clflush is run to get data out of the CPU caches
2725+ * then i915_dev_set_domain calls i915_gem_flush to
2726+ * emit an MI_FLUSH and drm_agp_chipset_flush
2727+ * 5. Unmapped from GTT
2728+ * i915_gem_object_unbind calls set_domain (CPU, CPU)
2729+ * flush_domains and invalidate_domains end up both zero
2730+ * so no flushing/invalidating happens
2731+ * 6. Freed
2732+ * yay, done
2733+ *
2734+ * Case 2: The shared render buffer
2735+ *
2736+ * 1. Allocated
2737+ * 2. Mapped to GTT
2738+ * 3. Read/written by GPU
2739+ * 4. set_domain to (CPU,CPU)
2740+ * 5. Read/written by CPU
2741+ * 6. Read/written by GPU
2742+ *
2743+ * 1. Allocated
2744+ * Same as last example, (CPU, CPU)
2745+ * 2. Mapped to GTT
2746+ * Nothing changes (assertions find that it is not in the GPU)
2747+ * 3. Read/written by GPU
2748+ * execbuffer calls set_domain (RENDER, RENDER)
2749+ * flush_domains gets CPU
2750+ * invalidate_domains gets GPU
2751+ * clflush (obj)
2752+ * MI_FLUSH and drm_agp_chipset_flush
2753+ * 4. set_domain (CPU, CPU)
2754+ * flush_domains gets GPU
2755+ * invalidate_domains gets CPU
2756+ * wait_rendering (obj) to make sure all drawing is complete.
2757+ * This will include an MI_FLUSH to get the data from GPU
2758+ * to memory
2759+ * clflush (obj) to invalidate the CPU cache
2760+ * Another MI_FLUSH in i915_gem_flush (eliminate this somehow?)
2761+ * 5. Read/written by CPU
2762+ * cache lines are loaded and dirtied
2763+ * 6. Read written by GPU
2764+ * Same as last GPU access
2765+ *
2766+ * Case 3: The constant buffer
2767+ *
2768+ * 1. Allocated
2769+ * 2. Written by CPU
2770+ * 3. Read by GPU
2771+ * 4. Updated (written) by CPU again
2772+ * 5. Read by GPU
2773+ *
2774+ * 1. Allocated
2775+ * (CPU, CPU)
2776+ * 2. Written by CPU
2777+ * (CPU, CPU)
2778+ * 3. Read by GPU
2779+ * (CPU+RENDER, 0)
2780+ * flush_domains = CPU
2781+ * invalidate_domains = RENDER
2782+ * clflush (obj)
2783+ * MI_FLUSH
2784+ * drm_agp_chipset_flush
2785+ * 4. Updated (written) by CPU again
2786+ * (CPU, CPU)
2787+ * flush_domains = 0 (no previous write domain)
2788+ * invalidate_domains = 0 (no new read domains)
2789+ * 5. Read by GPU
2790+ * (CPU+RENDER, 0)
2791+ * flush_domains = CPU
2792+ * invalidate_domains = RENDER
2793+ * clflush (obj)
2794+ * MI_FLUSH
2795+ * drm_agp_chipset_flush
2796+ */
2797+static int
2798+i915_gem_object_set_domain(struct drm_gem_object *obj,
2799+ uint32_t read_domains,
2800+ uint32_t write_domain)
2801+{
2802+ struct drm_device *dev = obj->dev;
2803+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
2804+ uint32_t invalidate_domains = 0;
2805+ uint32_t flush_domains = 0;
2806+ int ret;
2807+
2808+#if WATCH_BUF
2809+ DRM_INFO("%s: object %p read %08x -> %08x write %08x -> %08x\n",
2810+ __func__, obj,
2811+ obj->read_domains, read_domains,
2812+ obj->write_domain, write_domain);
2813+#endif
2814+ /*
2815+ * If the object isn't moving to a new write domain,
2816+ * let the object stay in multiple read domains
2817+ */
2818+ if (write_domain == 0)
2819+ read_domains |= obj->read_domains;
2820+ else
2821+ obj_priv->dirty = 1;
2822+
2823+ /*
2824+ * Flush the current write domain if
2825+ * the new read domains don't match. Invalidate
2826+ * any read domains which differ from the old
2827+ * write domain
2828+ */
2829+ if (obj->write_domain && obj->write_domain != read_domains) {
2830+ flush_domains |= obj->write_domain;
2831+ invalidate_domains |= read_domains & ~obj->write_domain;
2832+ }
2833+ /*
2834+ * Invalidate any read caches which may have
2835+ * stale data. That is, any new read domains.
2836+ */
2837+ invalidate_domains |= read_domains & ~obj->read_domains;
2838+ if ((flush_domains | invalidate_domains) & I915_GEM_DOMAIN_CPU) {
2839+#if WATCH_BUF
2840+ DRM_INFO("%s: CPU domain flush %08x invalidate %08x\n",
2841+ __func__, flush_domains, invalidate_domains);
2842+#endif
2843+ /*
2844+ * If we're invaliding the CPU cache and flushing a GPU cache,
2845+ * then pause for rendering so that the GPU caches will be
2846+ * flushed before the cpu cache is invalidated
2847+ */
2848+ if ((invalidate_domains & I915_GEM_DOMAIN_CPU) &&
2849+ (flush_domains & ~(I915_GEM_DOMAIN_CPU |
2850+ I915_GEM_DOMAIN_GTT))) {
2851+ ret = i915_gem_object_wait_rendering(obj);
2852+ if (ret)
2853+ return ret;
2854+ }
2855+ i915_gem_clflush_object(obj);
2856+ }
2857+
2858+ if ((write_domain | flush_domains) != 0)
2859+ obj->write_domain = write_domain;
2860+
2861+ /* If we're invalidating the CPU domain, clear the per-page CPU
2862+ * domain list as well.
2863+ */
2864+ if (obj_priv->page_cpu_valid != NULL &&
2865+ (write_domain != 0 ||
2866+ read_domains & I915_GEM_DOMAIN_CPU)) {
2867+ drm_free(obj_priv->page_cpu_valid, obj->size / PAGE_SIZE,
2868+ DRM_MEM_DRIVER);
2869+ obj_priv->page_cpu_valid = NULL;
2870+ }
2871+ obj->read_domains = read_domains;
2872+
2873+ dev->invalidate_domains |= invalidate_domains;
2874+ dev->flush_domains |= flush_domains;
2875+#if WATCH_BUF
2876+ DRM_INFO("%s: read %08x write %08x invalidate %08x flush %08x\n",
2877+ __func__,
2878+ obj->read_domains, obj->write_domain,
2879+ dev->invalidate_domains, dev->flush_domains);
2880+#endif
2881+ return 0;
2882+}
2883+
2884+/**
2885+ * Set the read/write domain on a range of the object.
2886+ *
2887+ * Currently only implemented for CPU reads, otherwise drops to normal
2888+ * i915_gem_object_set_domain().
2889+ */
2890+static int
2891+i915_gem_object_set_domain_range(struct drm_gem_object *obj,
2892+ uint64_t offset,
2893+ uint64_t size,
2894+ uint32_t read_domains,
2895+ uint32_t write_domain)
2896+{
2897+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
2898+ int ret, i;
2899+
2900+ if (obj->read_domains & I915_GEM_DOMAIN_CPU)
2901+ return 0;
2902+
2903+ if (read_domains != I915_GEM_DOMAIN_CPU ||
2904+ write_domain != 0)
2905+ return i915_gem_object_set_domain(obj,
2906+ read_domains, write_domain);
2907+
2908+ /* Wait on any GPU rendering to the object to be flushed. */
2909+ if (obj->write_domain & ~(I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT)) {
2910+ ret = i915_gem_object_wait_rendering(obj);
2911+ if (ret)
2912+ return ret;
2913+ }
2914+
2915+ if (obj_priv->page_cpu_valid == NULL) {
2916+ obj_priv->page_cpu_valid = drm_calloc(1, obj->size / PAGE_SIZE,
2917+ DRM_MEM_DRIVER);
2918+ }
2919+
2920+ /* Flush the cache on any pages that are still invalid from the CPU's
2921+ * perspective.
2922+ */
2923+ for (i = offset / PAGE_SIZE; i <= (offset + size - 1) / PAGE_SIZE; i++) {
2924+ if (obj_priv->page_cpu_valid[i])
2925+ continue;
2926+
2927+ drm_clflush_pages(obj_priv->page_list + i, 1);
2928+
2929+ obj_priv->page_cpu_valid[i] = 1;
2930+ }
2931+
2932+ return 0;
2933+}
2934+
2935+/**
2936+ * Once all of the objects have been set in the proper domain,
2937+ * perform the necessary flush and invalidate operations.
2938+ *
2939+ * Returns the write domains flushed, for use in flush tracking.
2940+ */
2941+static uint32_t
2942+i915_gem_dev_set_domain(struct drm_device *dev)
2943+{
2944+ uint32_t flush_domains = dev->flush_domains;
2945+
2946+ /*
2947+ * Now that all the buffers are synced to the proper domains,
2948+ * flush and invalidate the collected domains
2949+ */
2950+ if (dev->invalidate_domains | dev->flush_domains) {
2951+#if WATCH_EXEC
2952+ DRM_INFO("%s: invalidate_domains %08x flush_domains %08x\n",
2953+ __func__,
2954+ dev->invalidate_domains,
2955+ dev->flush_domains);
2956+#endif
2957+ i915_gem_flush(dev,
2958+ dev->invalidate_domains,
2959+ dev->flush_domains);
2960+ dev->invalidate_domains = 0;
2961+ dev->flush_domains = 0;
2962+ }
2963+
2964+ return flush_domains;
2965+}
2966+
2967+/**
2968+ * Pin an object to the GTT and evaluate the relocations landing in it.
2969+ */
2970+static int
2971+i915_gem_object_pin_and_relocate(struct drm_gem_object *obj,
2972+ struct drm_file *file_priv,
2973+ struct drm_i915_gem_exec_object *entry)
2974+{
2975+ struct drm_device *dev = obj->dev;
2976+ struct drm_i915_gem_relocation_entry reloc;
2977+ struct drm_i915_gem_relocation_entry __user *relocs;
2978+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
2979+ int i, ret;
2980+ uint32_t last_reloc_offset = -1;
2981+ void *reloc_page = NULL;
2982+
2983+ /* Choose the GTT offset for our buffer and put it there. */
2984+ ret = i915_gem_object_pin(obj, (uint32_t) entry->alignment);
2985+ if (ret)
2986+ return ret;
2987+
2988+ entry->offset = obj_priv->gtt_offset;
2989+
2990+ relocs = (struct drm_i915_gem_relocation_entry __user *)
2991+ (uintptr_t) entry->relocs_ptr;
2992+ /* Apply the relocations, using the GTT aperture to avoid cache
2993+ * flushing requirements.
2994+ */
2995+ for (i = 0; i < entry->relocation_count; i++) {
2996+ struct drm_gem_object *target_obj;
2997+ struct drm_i915_gem_object *target_obj_priv;
2998+ uint32_t reloc_val, reloc_offset, *reloc_entry;
2999+ int ret;
3000+
3001+ ret = copy_from_user(&reloc, relocs + i, sizeof(reloc));
3002+ if (ret != 0) {
3003+ i915_gem_object_unpin(obj);
3004+ return ret;
3005+ }
3006+
3007+ target_obj = drm_gem_object_lookup(obj->dev, file_priv,
3008+ reloc.target_handle);
3009+ if (target_obj == NULL) {
3010+ i915_gem_object_unpin(obj);
3011+ return -EBADF;
3012+ }
3013+ target_obj_priv = target_obj->driver_private;
3014+
3015+ /* The target buffer should have appeared before us in the
3016+ * exec_object list, so it should have a GTT space bound by now.
3017+ */
3018+ if (target_obj_priv->gtt_space == NULL) {
3019+ DRM_ERROR("No GTT space found for object %d\n",
3020+ reloc.target_handle);
3021+ drm_gem_object_unreference(target_obj);
3022+ i915_gem_object_unpin(obj);
3023+ return -EINVAL;
3024+ }
3025+
3026+ if (reloc.offset > obj->size - 4) {
3027+ DRM_ERROR("Relocation beyond object bounds: "
3028+ "obj %p target %d offset %d size %d.\n",
3029+ obj, reloc.target_handle,
3030+ (int) reloc.offset, (int) obj->size);
3031+ drm_gem_object_unreference(target_obj);
3032+ i915_gem_object_unpin(obj);
3033+ return -EINVAL;
3034+ }
3035+ if (reloc.offset & 3) {
3036+ DRM_ERROR("Relocation not 4-byte aligned: "
3037+ "obj %p target %d offset %d.\n",
3038+ obj, reloc.target_handle,
3039+ (int) reloc.offset);
3040+ drm_gem_object_unreference(target_obj);
3041+ i915_gem_object_unpin(obj);
3042+ return -EINVAL;
3043+ }
3044+
3045+ if (reloc.write_domain && target_obj->pending_write_domain &&
3046+ reloc.write_domain != target_obj->pending_write_domain) {
3047+ DRM_ERROR("Write domain conflict: "
3048+ "obj %p target %d offset %d "
3049+ "new %08x old %08x\n",
3050+ obj, reloc.target_handle,
3051+ (int) reloc.offset,
3052+ reloc.write_domain,
3053+ target_obj->pending_write_domain);
3054+ drm_gem_object_unreference(target_obj);
3055+ i915_gem_object_unpin(obj);
3056+ return -EINVAL;
3057+ }
3058+
3059+#if WATCH_RELOC
3060+ DRM_INFO("%s: obj %p offset %08x target %d "
3061+ "read %08x write %08x gtt %08x "
3062+ "presumed %08x delta %08x\n",
3063+ __func__,
3064+ obj,
3065+ (int) reloc.offset,
3066+ (int) reloc.target_handle,
3067+ (int) reloc.read_domains,
3068+ (int) reloc.write_domain,
3069+ (int) target_obj_priv->gtt_offset,
3070+ (int) reloc.presumed_offset,
3071+ reloc.delta);
3072+#endif
3073+
3074+ target_obj->pending_read_domains |= reloc.read_domains;
3075+ target_obj->pending_write_domain |= reloc.write_domain;
3076+
3077+ /* If the relocation already has the right value in it, no
3078+ * more work needs to be done.
3079+ */
3080+ if (target_obj_priv->gtt_offset == reloc.presumed_offset) {
3081+ drm_gem_object_unreference(target_obj);
3082+ continue;
3083+ }
3084+
3085+ /* Now that we're going to actually write some data in,
3086+ * make sure that any rendering using this buffer's contents
3087+ * is completed.
3088+ */
3089+ i915_gem_object_wait_rendering(obj);
3090+
3091+ /* As we're writing through the gtt, flush
3092+ * any CPU writes before we write the relocations
3093+ */
3094+ if (obj->write_domain & I915_GEM_DOMAIN_CPU) {
3095+ i915_gem_clflush_object(obj);
3096+ drm_agp_chipset_flush(dev);
3097+ obj->write_domain = 0;
3098+ }
3099+
3100+ /* Map the page containing the relocation we're going to
3101+ * perform.
3102+ */
3103+ reloc_offset = obj_priv->gtt_offset + reloc.offset;
3104+ if (reloc_page == NULL ||
3105+ (last_reloc_offset & ~(PAGE_SIZE - 1)) !=
3106+ (reloc_offset & ~(PAGE_SIZE - 1))) {
3107+ if (reloc_page != NULL)
3108+ iounmap(reloc_page);
3109+
3110+ reloc_page = ioremap(dev->agp->base +
3111+ (reloc_offset & ~(PAGE_SIZE - 1)),
3112+ PAGE_SIZE);
3113+ last_reloc_offset = reloc_offset;
3114+ if (reloc_page == NULL) {
3115+ drm_gem_object_unreference(target_obj);
3116+ i915_gem_object_unpin(obj);
3117+ return -ENOMEM;
3118+ }
3119+ }
3120+
3121+ reloc_entry = (uint32_t *)((char *)reloc_page +
3122+ (reloc_offset & (PAGE_SIZE - 1)));
3123+ reloc_val = target_obj_priv->gtt_offset + reloc.delta;
3124+
3125+#if WATCH_BUF
3126+ DRM_INFO("Applied relocation: %p@0x%08x %08x -> %08x\n",
3127+ obj, (unsigned int) reloc.offset,
3128+ readl(reloc_entry), reloc_val);
3129+#endif
3130+ writel(reloc_val, reloc_entry);
3131+
3132+ /* Write the updated presumed offset for this entry back out
3133+ * to the user.
3134+ */
3135+ reloc.presumed_offset = target_obj_priv->gtt_offset;
3136+ ret = copy_to_user(relocs + i, &reloc, sizeof(reloc));
3137+ if (ret != 0) {
3138+ drm_gem_object_unreference(target_obj);
3139+ i915_gem_object_unpin(obj);
3140+ return ret;
3141+ }
3142+
3143+ drm_gem_object_unreference(target_obj);
3144+ }
3145+
3146+ if (reloc_page != NULL)
3147+ iounmap(reloc_page);
3148+
3149+#if WATCH_BUF
3150+ if (0)
3151+ i915_gem_dump_object(obj, 128, __func__, ~0);
3152+#endif
3153+ return 0;
3154+}
3155+
3156+/** Dispatch a batchbuffer to the ring
3157+ */
3158+static int
3159+i915_dispatch_gem_execbuffer(struct drm_device *dev,
3160+ struct drm_i915_gem_execbuffer *exec,
3161+ uint64_t exec_offset)
3162+{
3163+ drm_i915_private_t *dev_priv = dev->dev_private;
3164+ struct drm_clip_rect __user *boxes = (struct drm_clip_rect __user *)
3165+ (uintptr_t) exec->cliprects_ptr;
3166+ int nbox = exec->num_cliprects;
3167+ int i = 0, count;
3168+ uint32_t exec_start, exec_len;
3169+ RING_LOCALS;
3170+
3171+ exec_start = (uint32_t) exec_offset + exec->batch_start_offset;
3172+ exec_len = (uint32_t) exec->batch_len;
3173+
3174+ if ((exec_start | exec_len) & 0x7) {
3175+ DRM_ERROR("alignment\n");
3176+ return -EINVAL;
3177+ }
3178+
3179+ if (!exec_start)
3180+ return -EINVAL;
3181+
3182+ count = nbox ? nbox : 1;
3183+
3184+ for (i = 0; i < count; i++) {
3185+ if (i < nbox) {
3186+ int ret = i915_emit_box(dev, boxes, i,
3187+ exec->DR1, exec->DR4);
3188+ if (ret)
3189+ return ret;
3190+ }
3191+
3192+ if (IS_I830(dev) || IS_845G(dev)) {
3193+ BEGIN_LP_RING(4);
3194+ OUT_RING(MI_BATCH_BUFFER);
3195+ OUT_RING(exec_start | MI_BATCH_NON_SECURE);
3196+ OUT_RING(exec_start + exec_len - 4);
3197+ OUT_RING(0);
3198+ ADVANCE_LP_RING();
3199+ } else {
3200+ BEGIN_LP_RING(2);
3201+ if (IS_I965G(dev)) {
3202+ OUT_RING(MI_BATCH_BUFFER_START |
3203+ (2 << 6) |
3204+ MI_BATCH_NON_SECURE_I965);
3205+ OUT_RING(exec_start);
3206+ } else {
3207+ OUT_RING(MI_BATCH_BUFFER_START |
3208+ (2 << 6));
3209+ OUT_RING(exec_start | MI_BATCH_NON_SECURE);
3210+ }
3211+ ADVANCE_LP_RING();
3212+ }
3213+ }
3214+
3215+ /* XXX breadcrumb */
3216+ return 0;
3217+}
3218+
3219+/* Throttle our rendering by waiting until the ring has completed our requests
3220+ * emitted over 20 msec ago.
3221+ *
3222+ * This should get us reasonable parallelism between CPU and GPU but also
3223+ * relatively low latency when blocking on a particular request to finish.
3224+ */
3225+static int
3226+i915_gem_ring_throttle(struct drm_device *dev, struct drm_file *file_priv)
3227+{
3228+ struct drm_i915_file_private *i915_file_priv = file_priv->driver_priv;
3229+ int ret = 0;
3230+ uint32_t seqno;
3231+
3232+ mutex_lock(&dev->struct_mutex);
3233+ seqno = i915_file_priv->mm.last_gem_throttle_seqno;
3234+ i915_file_priv->mm.last_gem_throttle_seqno =
3235+ i915_file_priv->mm.last_gem_seqno;
3236+ if (seqno)
3237+ ret = i915_wait_request(dev, seqno);
3238+ mutex_unlock(&dev->struct_mutex);
3239+ return ret;
3240+}
3241+
3242+int
3243+i915_gem_execbuffer(struct drm_device *dev, void *data,
3244+ struct drm_file *file_priv)
3245+{
3246+ drm_i915_private_t *dev_priv = dev->dev_private;
3247+ struct drm_i915_file_private *i915_file_priv = file_priv->driver_priv;
3248+ struct drm_i915_gem_execbuffer *args = data;
3249+ struct drm_i915_gem_exec_object *exec_list = NULL;
3250+ struct drm_gem_object **object_list = NULL;
3251+ struct drm_gem_object *batch_obj;
3252+ int ret, i, pinned = 0;
3253+ uint64_t exec_offset;
3254+ uint32_t seqno, flush_domains;
3255+
3256+#if WATCH_EXEC
3257+ DRM_INFO("buffers_ptr %d buffer_count %d len %08x\n",
3258+ (int) args->buffers_ptr, args->buffer_count, args->batch_len);
3259+#endif
3260+
3261+ /* Copy in the exec list from userland */
3262+ exec_list = drm_calloc(sizeof(*exec_list), args->buffer_count,
3263+ DRM_MEM_DRIVER);
3264+ object_list = drm_calloc(sizeof(*object_list), args->buffer_count,
3265+ DRM_MEM_DRIVER);
3266+ if (exec_list == NULL || object_list == NULL) {
3267+ DRM_ERROR("Failed to allocate exec or object list "
3268+ "for %d buffers\n",
3269+ args->buffer_count);
3270+ ret = -ENOMEM;
3271+ goto pre_mutex_err;
3272+ }
3273+ ret = copy_from_user(exec_list,
3274+ (struct drm_i915_relocation_entry __user *)
3275+ (uintptr_t) args->buffers_ptr,
3276+ sizeof(*exec_list) * args->buffer_count);
3277+ if (ret != 0) {
3278+ DRM_ERROR("copy %d exec entries failed %d\n",
3279+ args->buffer_count, ret);
3280+ goto pre_mutex_err;
3281+ }
3282+
3283+ mutex_lock(&dev->struct_mutex);
3284+
3285+ i915_verify_inactive(dev, __FILE__, __LINE__);
3286+
3287+ if (dev_priv->mm.wedged) {
3288+ DRM_ERROR("Execbuf while wedged\n");
3289+ mutex_unlock(&dev->struct_mutex);
3290+ return -EIO;
3291+ }
3292+
3293+ if (dev_priv->mm.suspended) {
3294+ DRM_ERROR("Execbuf while VT-switched.\n");
3295+ mutex_unlock(&dev->struct_mutex);
3296+ return -EBUSY;
3297+ }
3298+
3299+ /* Zero the gloabl flush/invalidate flags. These
3300+ * will be modified as each object is bound to the
3301+ * gtt
3302+ */
3303+ dev->invalidate_domains = 0;
3304+ dev->flush_domains = 0;
3305+
3306+ /* Look up object handles and perform the relocations */
3307+ for (i = 0; i < args->buffer_count; i++) {
3308+ object_list[i] = drm_gem_object_lookup(dev, file_priv,
3309+ exec_list[i].handle);
3310+ if (object_list[i] == NULL) {
3311+ DRM_ERROR("Invalid object handle %d at index %d\n",
3312+ exec_list[i].handle, i);
3313+ ret = -EBADF;
3314+ goto err;
3315+ }
3316+
3317+ object_list[i]->pending_read_domains = 0;
3318+ object_list[i]->pending_write_domain = 0;
3319+ ret = i915_gem_object_pin_and_relocate(object_list[i],
3320+ file_priv,
3321+ &exec_list[i]);
3322+ if (ret) {
3323+ DRM_ERROR("object bind and relocate failed %d\n", ret);
3324+ goto err;
3325+ }
3326+ pinned = i + 1;
3327+ }
3328+
3329+ /* Set the pending read domains for the batch buffer to COMMAND */
3330+ batch_obj = object_list[args->buffer_count-1];
3331+ batch_obj->pending_read_domains = I915_GEM_DOMAIN_COMMAND;
3332+ batch_obj->pending_write_domain = 0;
3333+
3334+ i915_verify_inactive(dev, __FILE__, __LINE__);
3335+
3336+ for (i = 0; i < args->buffer_count; i++) {
3337+ struct drm_gem_object *obj = object_list[i];
3338+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
3339+
3340+ if (obj_priv->gtt_space == NULL) {
3341+ /* We evicted the buffer in the process of validating
3342+ * our set of buffers in. We could try to recover by
3343+ * kicking them everything out and trying again from
3344+ * the start.
3345+ */
3346+ ret = -ENOMEM;
3347+ goto err;
3348+ }
3349+
3350+ /* make sure all previous memory operations have passed */
3351+ ret = i915_gem_object_set_domain(obj,
3352+ obj->pending_read_domains,
3353+ obj->pending_write_domain);
3354+ if (ret)
3355+ goto err;
3356+ }
3357+
3358+ i915_verify_inactive(dev, __FILE__, __LINE__);
3359+
3360+ /* Flush/invalidate caches and chipset buffer */
3361+ flush_domains = i915_gem_dev_set_domain(dev);
3362+
3363+ i915_verify_inactive(dev, __FILE__, __LINE__);
3364+
3365+#if WATCH_COHERENCY
3366+ for (i = 0; i < args->buffer_count; i++) {
3367+ i915_gem_object_check_coherency(object_list[i],
3368+ exec_list[i].handle);
3369+ }
3370+#endif
3371+
3372+ exec_offset = exec_list[args->buffer_count - 1].offset;
3373+
3374+#if WATCH_EXEC
3375+ i915_gem_dump_object(object_list[args->buffer_count - 1],
3376+ args->batch_len,
3377+ __func__,
3378+ ~0);
3379+#endif
3380+
3381+ (void)i915_add_request(dev, flush_domains);
3382+
3383+ /* Exec the batchbuffer */
3384+ ret = i915_dispatch_gem_execbuffer(dev, args, exec_offset);
3385+ if (ret) {
3386+ DRM_ERROR("dispatch failed %d\n", ret);
3387+ goto err;
3388+ }
3389+
3390+ /*
3391+ * Ensure that the commands in the batch buffer are
3392+ * finished before the interrupt fires
3393+ */
3394+ flush_domains = i915_retire_commands(dev);
3395+
3396+ i915_verify_inactive(dev, __FILE__, __LINE__);
3397+
3398+ /*
3399+ * Get a seqno representing the execution of the current buffer,
3400+ * which we can wait on. We would like to mitigate these interrupts,
3401+ * likely by only creating seqnos occasionally (so that we have
3402+ * *some* interrupts representing completion of buffers that we can
3403+ * wait on when trying to clear up gtt space).
3404+ */
3405+ seqno = i915_add_request(dev, flush_domains);
3406+ BUG_ON(seqno == 0);
3407+ i915_file_priv->mm.last_gem_seqno = seqno;
3408+ for (i = 0; i < args->buffer_count; i++) {
3409+ struct drm_gem_object *obj = object_list[i];
3410+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
3411+
3412+ i915_gem_object_move_to_active(obj);
3413+ obj_priv->last_rendering_seqno = seqno;
3414+#if WATCH_LRU
3415+ DRM_INFO("%s: move to exec list %p\n", __func__, obj);
3416+#endif
3417+ }
3418+#if WATCH_LRU
3419+ i915_dump_lru(dev, __func__);
3420+#endif
3421+
3422+ i915_verify_inactive(dev, __FILE__, __LINE__);
3423+
3424+ /* Copy the new buffer offsets back to the user's exec list. */
3425+ ret = copy_to_user((struct drm_i915_relocation_entry __user *)
3426+ (uintptr_t) args->buffers_ptr,
3427+ exec_list,
3428+ sizeof(*exec_list) * args->buffer_count);
3429+ if (ret)
3430+ DRM_ERROR("failed to copy %d exec entries "
3431+ "back to user (%d)\n",
3432+ args->buffer_count, ret);
3433+err:
3434+ if (object_list != NULL) {
3435+ for (i = 0; i < pinned; i++)
3436+ i915_gem_object_unpin(object_list[i]);
3437+
3438+ for (i = 0; i < args->buffer_count; i++)
3439+ drm_gem_object_unreference(object_list[i]);
3440+ }
3441+ mutex_unlock(&dev->struct_mutex);
3442+
3443+pre_mutex_err:
3444+ drm_free(object_list, sizeof(*object_list) * args->buffer_count,
3445+ DRM_MEM_DRIVER);
3446+ drm_free(exec_list, sizeof(*exec_list) * args->buffer_count,
3447+ DRM_MEM_DRIVER);
3448+
3449+ return ret;
3450+}
3451+
3452+int
3453+i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment)
3454+{
3455+ struct drm_device *dev = obj->dev;
3456+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
3457+ int ret;
3458+
3459+ i915_verify_inactive(dev, __FILE__, __LINE__);
3460+ if (obj_priv->gtt_space == NULL) {
3461+ ret = i915_gem_object_bind_to_gtt(obj, alignment);
3462+ if (ret != 0) {
3463+ DRM_ERROR("Failure to bind: %d", ret);
3464+ return ret;
3465+ }
3466+ }
3467+ obj_priv->pin_count++;
3468+
3469+ /* If the object is not active and not pending a flush,
3470+ * remove it from the inactive list
3471+ */
3472+ if (obj_priv->pin_count == 1) {
3473+ atomic_inc(&dev->pin_count);
3474+ atomic_add(obj->size, &dev->pin_memory);
3475+ if (!obj_priv->active &&
3476+ (obj->write_domain & ~(I915_GEM_DOMAIN_CPU |
3477+ I915_GEM_DOMAIN_GTT)) == 0 &&
3478+ !list_empty(&obj_priv->list))
3479+ list_del_init(&obj_priv->list);
3480+ }
3481+ i915_verify_inactive(dev, __FILE__, __LINE__);
3482+
3483+ return 0;
3484+}
3485+
3486+void
3487+i915_gem_object_unpin(struct drm_gem_object *obj)
3488+{
3489+ struct drm_device *dev = obj->dev;
3490+ drm_i915_private_t *dev_priv = dev->dev_private;
3491+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
3492+
3493+ i915_verify_inactive(dev, __FILE__, __LINE__);
3494+ obj_priv->pin_count--;
3495+ BUG_ON(obj_priv->pin_count < 0);
3496+ BUG_ON(obj_priv->gtt_space == NULL);
3497+
3498+ /* If the object is no longer pinned, and is
3499+ * neither active nor being flushed, then stick it on
3500+ * the inactive list
3501+ */
3502+ if (obj_priv->pin_count == 0) {
3503+ if (!obj_priv->active &&
3504+ (obj->write_domain & ~(I915_GEM_DOMAIN_CPU |
3505+ I915_GEM_DOMAIN_GTT)) == 0)
3506+ list_move_tail(&obj_priv->list,
3507+ &dev_priv->mm.inactive_list);
3508+ atomic_dec(&dev->pin_count);
3509+ atomic_sub(obj->size, &dev->pin_memory);
3510+ }
3511+ i915_verify_inactive(dev, __FILE__, __LINE__);
3512+}
3513+
3514+int
3515+i915_gem_pin_ioctl(struct drm_device *dev, void *data,
3516+ struct drm_file *file_priv)
3517+{
3518+ struct drm_i915_gem_pin *args = data;
3519+ struct drm_gem_object *obj;
3520+ struct drm_i915_gem_object *obj_priv;
3521+ int ret;
3522+
3523+ mutex_lock(&dev->struct_mutex);
3524+
3525+ obj = drm_gem_object_lookup(dev, file_priv, args->handle);
3526+ if (obj == NULL) {
3527+ DRM_ERROR("Bad handle in i915_gem_pin_ioctl(): %d\n",
3528+ args->handle);
3529+ mutex_unlock(&dev->struct_mutex);
3530+ return -EBADF;
3531+ }
3532+ obj_priv = obj->driver_private;
3533+
3534+ ret = i915_gem_object_pin(obj, args->alignment);
3535+ if (ret != 0) {
3536+ drm_gem_object_unreference(obj);
3537+ mutex_unlock(&dev->struct_mutex);
3538+ return ret;
3539+ }
3540+
3541+ /* XXX - flush the CPU caches for pinned objects
3542+ * as the X server doesn't manage domains yet
3543+ */
3544+ if (obj->write_domain & I915_GEM_DOMAIN_CPU) {
3545+ i915_gem_clflush_object(obj);
3546+ drm_agp_chipset_flush(dev);
3547+ obj->write_domain = 0;
3548+ }
3549+ args->offset = obj_priv->gtt_offset;
3550+ drm_gem_object_unreference(obj);
3551+ mutex_unlock(&dev->struct_mutex);
3552+
3553+ return 0;
3554+}
3555+
3556+int
3557+i915_gem_unpin_ioctl(struct drm_device *dev, void *data,
3558+ struct drm_file *file_priv)
3559+{
3560+ struct drm_i915_gem_pin *args = data;
3561+ struct drm_gem_object *obj;
3562+
3563+ mutex_lock(&dev->struct_mutex);
3564+
3565+ obj = drm_gem_object_lookup(dev, file_priv, args->handle);
3566+ if (obj == NULL) {
3567+ DRM_ERROR("Bad handle in i915_gem_unpin_ioctl(): %d\n",
3568+ args->handle);
3569+ mutex_unlock(&dev->struct_mutex);
3570+ return -EBADF;
3571+ }
3572+
3573+ i915_gem_object_unpin(obj);
3574+
3575+ drm_gem_object_unreference(obj);
3576+ mutex_unlock(&dev->struct_mutex);
3577+ return 0;
3578+}
3579+
3580+int
3581+i915_gem_busy_ioctl(struct drm_device *dev, void *data,
3582+ struct drm_file *file_priv)
3583+{
3584+ struct drm_i915_gem_busy *args = data;
3585+ struct drm_gem_object *obj;
3586+ struct drm_i915_gem_object *obj_priv;
3587+
3588+ mutex_lock(&dev->struct_mutex);
3589+ obj = drm_gem_object_lookup(dev, file_priv, args->handle);
3590+ if (obj == NULL) {
3591+ DRM_ERROR("Bad handle in i915_gem_busy_ioctl(): %d\n",
3592+ args->handle);
3593+ mutex_unlock(&dev->struct_mutex);
3594+ return -EBADF;
3595+ }
3596+
3597+ obj_priv = obj->driver_private;
3598+ args->busy = obj_priv->active;
3599+
3600+ drm_gem_object_unreference(obj);
3601+ mutex_unlock(&dev->struct_mutex);
3602+ return 0;
3603+}
3604+
3605+int
3606+i915_gem_throttle_ioctl(struct drm_device *dev, void *data,
3607+ struct drm_file *file_priv)
3608+{
3609+ return i915_gem_ring_throttle(dev, file_priv);
3610+}
3611+
3612+int i915_gem_init_object(struct drm_gem_object *obj)
3613+{
3614+ struct drm_i915_gem_object *obj_priv;
3615+
3616+ obj_priv = drm_calloc(1, sizeof(*obj_priv), DRM_MEM_DRIVER);
3617+ if (obj_priv == NULL)
3618+ return -ENOMEM;
3619+
3620+ /*
3621+ * We've just allocated pages from the kernel,
3622+ * so they've just been written by the CPU with
3623+ * zeros. They'll need to be clflushed before we
3624+ * use them with the GPU.
3625+ */
3626+ obj->write_domain = I915_GEM_DOMAIN_CPU;
3627+ obj->read_domains = I915_GEM_DOMAIN_CPU;
3628+
3629+ obj->driver_private = obj_priv;
3630+ obj_priv->obj = obj;
3631+ INIT_LIST_HEAD(&obj_priv->list);
3632+ return 0;
3633+}
3634+
3635+void i915_gem_free_object(struct drm_gem_object *obj)
3636+{
3637+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
3638+
3639+ while (obj_priv->pin_count > 0)
3640+ i915_gem_object_unpin(obj);
3641+
3642+ i915_gem_object_unbind(obj);
3643+
3644+ drm_free(obj_priv->page_cpu_valid, 1, DRM_MEM_DRIVER);
3645+ drm_free(obj->driver_private, 1, DRM_MEM_DRIVER);
3646+}
3647+
3648+static int
3649+i915_gem_set_domain(struct drm_gem_object *obj,
3650+ struct drm_file *file_priv,
3651+ uint32_t read_domains,
3652+ uint32_t write_domain)
3653+{
3654+ struct drm_device *dev = obj->dev;
3655+ int ret;
3656+ uint32_t flush_domains;
3657+
3658+ BUG_ON(!mutex_is_locked(&dev->struct_mutex));
3659+
3660+ ret = i915_gem_object_set_domain(obj, read_domains, write_domain);
3661+ if (ret)
3662+ return ret;
3663+ flush_domains = i915_gem_dev_set_domain(obj->dev);
3664+
3665+ if (flush_domains & ~(I915_GEM_DOMAIN_CPU|I915_GEM_DOMAIN_GTT))
3666+ (void) i915_add_request(dev, flush_domains);
3667+
3668+ return 0;
3669+}
3670+
3671+/** Unbinds all objects that are on the given buffer list. */
3672+static int
3673+i915_gem_evict_from_list(struct drm_device *dev, struct list_head *head)
3674+{
3675+ struct drm_gem_object *obj;
3676+ struct drm_i915_gem_object *obj_priv;
3677+ int ret;
3678+
3679+ while (!list_empty(head)) {
3680+ obj_priv = list_first_entry(head,
3681+ struct drm_i915_gem_object,
3682+ list);
3683+ obj = obj_priv->obj;
3684+
3685+ if (obj_priv->pin_count != 0) {
3686+ DRM_ERROR("Pinned object in unbind list\n");
3687+ mutex_unlock(&dev->struct_mutex);
3688+ return -EINVAL;
3689+ }
3690+
3691+ ret = i915_gem_object_unbind(obj);
3692+ if (ret != 0) {
3693+ DRM_ERROR("Error unbinding object in LeaveVT: %d\n",
3694+ ret);
3695+ mutex_unlock(&dev->struct_mutex);
3696+ return ret;
3697+ }
3698+ }
3699+
3700+
3701+ return 0;
3702+}
3703+
3704+static int
3705+i915_gem_idle(struct drm_device *dev)
3706+{
3707+ drm_i915_private_t *dev_priv = dev->dev_private;
3708+ uint32_t seqno, cur_seqno, last_seqno;
3709+ int stuck, ret;
3710+
3711+ if (dev_priv->mm.suspended)
3712+ return 0;
3713+
3714+ /* Hack! Don't let anybody do execbuf while we don't control the chip.
3715+ * We need to replace this with a semaphore, or something.
3716+ */
3717+ dev_priv->mm.suspended = 1;
3718+
3719+ i915_kernel_lost_context(dev);
3720+
3721+ /* Flush the GPU along with all non-CPU write domains
3722+ */
3723+ i915_gem_flush(dev, ~(I915_GEM_DOMAIN_CPU|I915_GEM_DOMAIN_GTT),
3724+ ~(I915_GEM_DOMAIN_CPU|I915_GEM_DOMAIN_GTT));
3725+ seqno = i915_add_request(dev, ~(I915_GEM_DOMAIN_CPU |
3726+ I915_GEM_DOMAIN_GTT));
3727+
3728+ if (seqno == 0) {
3729+ mutex_unlock(&dev->struct_mutex);
3730+ return -ENOMEM;
3731+ }
3732+
3733+ dev_priv->mm.waiting_gem_seqno = seqno;
3734+ last_seqno = 0;
3735+ stuck = 0;
3736+ for (;;) {
3737+ cur_seqno = i915_get_gem_seqno(dev);
3738+ if (i915_seqno_passed(cur_seqno, seqno))
3739+ break;
3740+ if (last_seqno == cur_seqno) {
3741+ if (stuck++ > 100) {
3742+ DRM_ERROR("hardware wedged\n");
3743+ dev_priv->mm.wedged = 1;
3744+ DRM_WAKEUP(&dev_priv->irq_queue);
3745+ break;
3746+ }
3747+ }
3748+ msleep(10);
3749+ last_seqno = cur_seqno;
3750+ }
3751+ dev_priv->mm.waiting_gem_seqno = 0;
3752+
3753+ i915_gem_retire_requests(dev);
3754+
3755+ /* Active and flushing should now be empty as we've
3756+ * waited for a sequence higher than any pending execbuffer
3757+ */
3758+ BUG_ON(!list_empty(&dev_priv->mm.active_list));
3759+ BUG_ON(!list_empty(&dev_priv->mm.flushing_list));
3760+
3761+ /* Request should now be empty as we've also waited
3762+ * for the last request in the list
3763+ */
3764+ BUG_ON(!list_empty(&dev_priv->mm.request_list));
3765+
3766+ /* Move all buffers out of the GTT. */
3767+ ret = i915_gem_evict_from_list(dev, &dev_priv->mm.inactive_list);
3768+ if (ret)
3769+ return ret;
3770+
3771+ BUG_ON(!list_empty(&dev_priv->mm.active_list));
3772+ BUG_ON(!list_empty(&dev_priv->mm.flushing_list));
3773+ BUG_ON(!list_empty(&dev_priv->mm.inactive_list));
3774+ BUG_ON(!list_empty(&dev_priv->mm.request_list));
3775+ return 0;
3776+}
3777+
3778+static int
3779+i915_gem_init_hws(struct drm_device *dev)
3780+{
3781+ drm_i915_private_t *dev_priv = dev->dev_private;
3782+ struct drm_gem_object *obj;
3783+ struct drm_i915_gem_object *obj_priv;
3784+ int ret;
3785+
3786+ /* If we need a physical address for the status page, it's already
3787+ * initialized at driver load time.
3788+ */
3789+ if (!I915_NEED_GFX_HWS(dev))
3790+ return 0;
3791+
3792+ obj = drm_gem_object_alloc(dev, 4096);
3793+ if (obj == NULL) {
3794+ DRM_ERROR("Failed to allocate status page\n");
3795+ return -ENOMEM;
3796+ }
3797+ obj_priv = obj->driver_private;
3798+
3799+ ret = i915_gem_object_pin(obj, 4096);
3800+ if (ret != 0) {
3801+ drm_gem_object_unreference(obj);
3802+ return ret;
3803+ }
3804+
3805+ dev_priv->status_gfx_addr = obj_priv->gtt_offset;
3806+ dev_priv->hws_map.offset = dev->agp->base + obj_priv->gtt_offset;
3807+ dev_priv->hws_map.size = 4096;
3808+ dev_priv->hws_map.type = 0;
3809+ dev_priv->hws_map.flags = 0;
3810+ dev_priv->hws_map.mtrr = 0;
3811+
3812+ drm_core_ioremap(&dev_priv->hws_map, dev);
3813+ if (dev_priv->hws_map.handle == NULL) {
3814+ DRM_ERROR("Failed to map status page.\n");
3815+ memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map));
3816+ drm_gem_object_unreference(obj);
3817+ return -EINVAL;
3818+ }
3819+ dev_priv->hws_obj = obj;
3820+ dev_priv->hw_status_page = dev_priv->hws_map.handle;
3821+ memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
3822+ I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr);
3823+ DRM_DEBUG("hws offset: 0x%08x\n", dev_priv->status_gfx_addr);
3824+
3825+ return 0;
3826+}
3827+
3828+static int
3829+i915_gem_init_ringbuffer(struct drm_device *dev)
3830+{
3831+ drm_i915_private_t *dev_priv = dev->dev_private;
3832+ struct drm_gem_object *obj;
3833+ struct drm_i915_gem_object *obj_priv;
3834+ int ret;
3835+
3836+ ret = i915_gem_init_hws(dev);
3837+ if (ret != 0)
3838+ return ret;
3839+
3840+ obj = drm_gem_object_alloc(dev, 128 * 1024);
3841+ if (obj == NULL) {
3842+ DRM_ERROR("Failed to allocate ringbuffer\n");
3843+ return -ENOMEM;
3844+ }
3845+ obj_priv = obj->driver_private;
3846+
3847+ ret = i915_gem_object_pin(obj, 4096);
3848+ if (ret != 0) {
3849+ drm_gem_object_unreference(obj);
3850+ return ret;
3851+ }
3852+
3853+ /* Set up the kernel mapping for the ring. */
3854+ dev_priv->ring.Size = obj->size;
3855+ dev_priv->ring.tail_mask = obj->size - 1;
3856+
3857+ dev_priv->ring.map.offset = dev->agp->base + obj_priv->gtt_offset;
3858+ dev_priv->ring.map.size = obj->size;
3859+ dev_priv->ring.map.type = 0;
3860+ dev_priv->ring.map.flags = 0;
3861+ dev_priv->ring.map.mtrr = 0;
3862+
3863+ drm_core_ioremap(&dev_priv->ring.map, dev);
3864+ if (dev_priv->ring.map.handle == NULL) {
3865+ DRM_ERROR("Failed to map ringbuffer.\n");
3866+ memset(&dev_priv->ring, 0, sizeof(dev_priv->ring));
3867+ drm_gem_object_unreference(obj);
3868+ return -EINVAL;
3869+ }
3870+ dev_priv->ring.ring_obj = obj;
3871+ dev_priv->ring.virtual_start = dev_priv->ring.map.handle;
3872+
3873+ /* Stop the ring if it's running. */
3874+ I915_WRITE(PRB0_CTL, 0);
3875+ I915_WRITE(PRB0_HEAD, 0);
3876+ I915_WRITE(PRB0_TAIL, 0);
3877+ I915_WRITE(PRB0_START, 0);
3878+
3879+ /* Initialize the ring. */
3880+ I915_WRITE(PRB0_START, obj_priv->gtt_offset);
3881+ I915_WRITE(PRB0_CTL,
3882+ ((obj->size - 4096) & RING_NR_PAGES) |
3883+ RING_NO_REPORT |
3884+ RING_VALID);
3885+
3886+ /* Update our cache of the ring state */
3887+ i915_kernel_lost_context(dev);
3888+
3889+ return 0;
3890+}
3891+
3892+static void
3893+i915_gem_cleanup_ringbuffer(struct drm_device *dev)
3894+{
3895+ drm_i915_private_t *dev_priv = dev->dev_private;
3896+
3897+ if (dev_priv->ring.ring_obj == NULL)
3898+ return;
3899+
3900+ drm_core_ioremapfree(&dev_priv->ring.map, dev);
3901+
3902+ i915_gem_object_unpin(dev_priv->ring.ring_obj);
3903+ drm_gem_object_unreference(dev_priv->ring.ring_obj);
3904+ dev_priv->ring.ring_obj = NULL;
3905+ memset(&dev_priv->ring, 0, sizeof(dev_priv->ring));
3906+
3907+ if (dev_priv->hws_obj != NULL) {
3908+ i915_gem_object_unpin(dev_priv->hws_obj);
3909+ drm_gem_object_unreference(dev_priv->hws_obj);
3910+ dev_priv->hws_obj = NULL;
3911+ memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map));
3912+
3913+ /* Write high address into HWS_PGA when disabling. */
3914+ I915_WRITE(HWS_PGA, 0x1ffff000);
3915+ }
3916+}
3917+
3918+int
3919+i915_gem_entervt_ioctl(struct drm_device *dev, void *data,
3920+ struct drm_file *file_priv)
3921+{
3922+ drm_i915_private_t *dev_priv = dev->dev_private;
3923+ int ret;
3924+
3925+ if (dev_priv->mm.wedged) {
3926+ DRM_ERROR("Reenabling wedged hardware, good luck\n");
3927+ dev_priv->mm.wedged = 0;
3928+ }
3929+
3930+ ret = i915_gem_init_ringbuffer(dev);
3931+ if (ret != 0)
3932+ return ret;
3933+
3934+ mutex_lock(&dev->struct_mutex);
3935+ BUG_ON(!list_empty(&dev_priv->mm.active_list));
3936+ BUG_ON(!list_empty(&dev_priv->mm.flushing_list));
3937+ BUG_ON(!list_empty(&dev_priv->mm.inactive_list));
3938+ BUG_ON(!list_empty(&dev_priv->mm.request_list));
3939+ dev_priv->mm.suspended = 0;
3940+ mutex_unlock(&dev->struct_mutex);
3941+ return 0;
3942+}
3943+
3944+int
3945+i915_gem_leavevt_ioctl(struct drm_device *dev, void *data,
3946+ struct drm_file *file_priv)
3947+{
3948+ int ret;
3949+
3950+ mutex_lock(&dev->struct_mutex);
3951+ ret = i915_gem_idle(dev);
3952+ if (ret == 0)
3953+ i915_gem_cleanup_ringbuffer(dev);
3954+ mutex_unlock(&dev->struct_mutex);
3955+
3956+ return 0;
3957+}
3958+
3959+void
3960+i915_gem_lastclose(struct drm_device *dev)
3961+{
3962+ int ret;
3963+ drm_i915_private_t *dev_priv = dev->dev_private;
3964+
3965+ mutex_lock(&dev->struct_mutex);
3966+
3967+ if (dev_priv->ring.ring_obj != NULL) {
3968+ ret = i915_gem_idle(dev);
3969+ if (ret)
3970+ DRM_ERROR("failed to idle hardware: %d\n", ret);
3971+
3972+ i915_gem_cleanup_ringbuffer(dev);
3973+ }
3974+
3975+ mutex_unlock(&dev->struct_mutex);
3976+}
3977+
3978+void
3979+i915_gem_load(struct drm_device *dev)
3980+{
3981+ drm_i915_private_t *dev_priv = dev->dev_private;
3982+
3983+ INIT_LIST_HEAD(&dev_priv->mm.active_list);
3984+ INIT_LIST_HEAD(&dev_priv->mm.flushing_list);
3985+ INIT_LIST_HEAD(&dev_priv->mm.inactive_list);
3986+ INIT_LIST_HEAD(&dev_priv->mm.request_list);
3987+ INIT_DELAYED_WORK(&dev_priv->mm.retire_work,
3988+ i915_gem_retire_work_handler);
3989+ dev_priv->mm.next_gem_seqno = 1;
3990+
3991+ i915_gem_detect_bit_6_swizzle(dev);
3992+}
3993diff --git a/drivers/gpu/drm/i915/i915_gem_debug.c b/drivers/gpu/drm/i915/i915_gem_debug.c
3994new file mode 100644
3995index 0000000..131c088
3996--- /dev/null
3997+++ b/drivers/gpu/drm/i915/i915_gem_debug.c
3998@@ -0,0 +1,201 @@
3999+/*
4000+ * Copyright © 2008 Intel Corporation
4001+ *
4002+ * Permission is hereby granted, free of charge, to any person obtaining a
4003+ * copy of this software and associated documentation files (the "Software"),
4004+ * to deal in the Software without restriction, including without limitation
4005+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
4006+ * and/or sell copies of the Software, and to permit persons to whom the
4007+ * Software is furnished to do so, subject to the following conditions:
4008+ *
4009+ * The above copyright notice and this permission notice (including the next
4010+ * paragraph) shall be included in all copies or substantial portions of the
4011+ * Software.
4012+ *
4013+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
4014+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
4015+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
4016+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
4017+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
4018+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
4019+ * IN THE SOFTWARE.
4020+ *
4021+ * Authors:
4022+ * Keith Packard <keithp@keithp.com>
4023+ *
4024+ */
4025+
4026+#include "drmP.h"
4027+#include "drm.h"
4028+#include "i915_drm.h"
4029+#include "i915_drv.h"
4030+
4031+#if WATCH_INACTIVE
4032+void
4033+i915_verify_inactive(struct drm_device *dev, char *file, int line)
4034+{
4035+ drm_i915_private_t *dev_priv = dev->dev_private;
4036+ struct drm_gem_object *obj;
4037+ struct drm_i915_gem_object *obj_priv;
4038+
4039+ list_for_each_entry(obj_priv, &dev_priv->mm.inactive_list, list) {
4040+ obj = obj_priv->obj;
4041+ if (obj_priv->pin_count || obj_priv->active ||
4042+ (obj->write_domain & ~(I915_GEM_DOMAIN_CPU |
4043+ I915_GEM_DOMAIN_GTT)))
4044+ DRM_ERROR("inactive %p (p %d a %d w %x) %s:%d\n",
4045+ obj,
4046+ obj_priv->pin_count, obj_priv->active,
4047+ obj->write_domain, file, line);
4048+ }
4049+}
4050+#endif /* WATCH_INACTIVE */
4051+
4052+
4053+#if WATCH_BUF | WATCH_EXEC | WATCH_PWRITE
4054+static void
4055+i915_gem_dump_page(struct page *page, uint32_t start, uint32_t end,
4056+ uint32_t bias, uint32_t mark)
4057+{
4058+ uint32_t *mem = kmap_atomic(page, KM_USER0);
4059+ int i;
4060+ for (i = start; i < end; i += 4)
4061+ DRM_INFO("%08x: %08x%s\n",
4062+ (int) (bias + i), mem[i / 4],
4063+ (bias + i == mark) ? " ********" : "");
4064+ kunmap_atomic(mem, KM_USER0);
4065+ /* give syslog time to catch up */
4066+ msleep(1);
4067+}
4068+
4069+void
4070+i915_gem_dump_object(struct drm_gem_object *obj, int len,
4071+ const char *where, uint32_t mark)
4072+{
4073+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
4074+ int page;
4075+
4076+ DRM_INFO("%s: object at offset %08x\n", where, obj_priv->gtt_offset);
4077+ for (page = 0; page < (len + PAGE_SIZE-1) / PAGE_SIZE; page++) {
4078+ int page_len, chunk, chunk_len;
4079+
4080+ page_len = len - page * PAGE_SIZE;
4081+ if (page_len > PAGE_SIZE)
4082+ page_len = PAGE_SIZE;
4083+
4084+ for (chunk = 0; chunk < page_len; chunk += 128) {
4085+ chunk_len = page_len - chunk;
4086+ if (chunk_len > 128)
4087+ chunk_len = 128;
4088+ i915_gem_dump_page(obj_priv->page_list[page],
4089+ chunk, chunk + chunk_len,
4090+ obj_priv->gtt_offset +
4091+ page * PAGE_SIZE,
4092+ mark);
4093+ }
4094+ }
4095+}
4096+#endif
4097+
4098+#if WATCH_LRU
4099+void
4100+i915_dump_lru(struct drm_device *dev, const char *where)
4101+{
4102+ drm_i915_private_t *dev_priv = dev->dev_private;
4103+ struct drm_i915_gem_object *obj_priv;
4104+
4105+ DRM_INFO("active list %s {\n", where);
4106+ list_for_each_entry(obj_priv, &dev_priv->mm.active_list,
4107+ list)
4108+ {
4109+ DRM_INFO(" %p: %08x\n", obj_priv,
4110+ obj_priv->last_rendering_seqno);
4111+ }
4112+ DRM_INFO("}\n");
4113+ DRM_INFO("flushing list %s {\n", where);
4114+ list_for_each_entry(obj_priv, &dev_priv->mm.flushing_list,
4115+ list)
4116+ {
4117+ DRM_INFO(" %p: %08x\n", obj_priv,
4118+ obj_priv->last_rendering_seqno);
4119+ }
4120+ DRM_INFO("}\n");
4121+ DRM_INFO("inactive %s {\n", where);
4122+ list_for_each_entry(obj_priv, &dev_priv->mm.inactive_list, list) {
4123+ DRM_INFO(" %p: %08x\n", obj_priv,
4124+ obj_priv->last_rendering_seqno);
4125+ }
4126+ DRM_INFO("}\n");
4127+}
4128+#endif
4129+
4130+
4131+#if WATCH_COHERENCY
4132+void
4133+i915_gem_object_check_coherency(struct drm_gem_object *obj, int handle)
4134+{
4135+ struct drm_device *dev = obj->dev;
4136+ struct drm_i915_gem_object *obj_priv = obj->driver_private;
4137+ int page;
4138+ uint32_t *gtt_mapping;
4139+ uint32_t *backing_map = NULL;
4140+ int bad_count = 0;
4141+
4142+ DRM_INFO("%s: checking coherency of object %p@0x%08x (%d, %dkb):\n",
4143+ __func__, obj, obj_priv->gtt_offset, handle,
4144+ obj->size / 1024);
4145+
4146+ gtt_mapping = ioremap(dev->agp->base + obj_priv->gtt_offset,
4147+ obj->size);
4148+ if (gtt_mapping == NULL) {
4149+ DRM_ERROR("failed to map GTT space\n");
4150+ return;
4151+ }
4152+
4153+ for (page = 0; page < obj->size / PAGE_SIZE; page++) {
4154+ int i;
4155+
4156+ backing_map = kmap_atomic(obj_priv->page_list[page], KM_USER0);
4157+
4158+ if (backing_map == NULL) {
4159+ DRM_ERROR("failed to map backing page\n");
4160+ goto out;
4161+ }
4162+
4163+ for (i = 0; i < PAGE_SIZE / 4; i++) {
4164+ uint32_t cpuval = backing_map[i];
4165+ uint32_t gttval = readl(gtt_mapping +
4166+ page * 1024 + i);
4167+
4168+ if (cpuval != gttval) {
4169+ DRM_INFO("incoherent CPU vs GPU at 0x%08x: "
4170+ "0x%08x vs 0x%08x\n",
4171+ (int)(obj_priv->gtt_offset +
4172+ page * PAGE_SIZE + i * 4),
4173+ cpuval, gttval);
4174+ if (bad_count++ >= 8) {
4175+ DRM_INFO("...\n");
4176+ goto out;
4177+ }
4178+ }
4179+ }
4180+ kunmap_atomic(backing_map, KM_USER0);
4181+ backing_map = NULL;
4182+ }
4183+
4184+ out:
4185+ if (backing_map != NULL)
4186+ kunmap_atomic(backing_map, KM_USER0);
4187+ iounmap(gtt_mapping);
4188+
4189+ /* give syslog time to catch up */
4190+ msleep(1);
4191+
4192+ /* Directly flush the object, since we just loaded values with the CPU
4193+ * from the backing pages and we don't want to disturb the cache
4194+ * management that we're trying to observe.
4195+ */
4196+
4197+ i915_gem_clflush_object(obj);
4198+}
4199+#endif
4200diff --git a/drivers/gpu/drm/i915/i915_gem_proc.c b/drivers/gpu/drm/i915/i915_gem_proc.c
4201new file mode 100644
4202index 0000000..15d4160
4203--- /dev/null
4204+++ b/drivers/gpu/drm/i915/i915_gem_proc.c
4205@@ -0,0 +1,292 @@
4206+/*
4207+ * Copyright © 2008 Intel Corporation
4208+ *
4209+ * Permission is hereby granted, free of charge, to any person obtaining a
4210+ * copy of this software and associated documentation files (the "Software"),
4211+ * to deal in the Software without restriction, including without limitation
4212+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
4213+ * and/or sell copies of the Software, and to permit persons to whom the
4214+ * Software is furnished to do so, subject to the following conditions:
4215+ *
4216+ * The above copyright notice and this permission notice (including the next
4217+ * paragraph) shall be included in all copies or substantial portions of the
4218+ * Software.
4219+ *
4220+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
4221+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
4222+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
4223+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
4224+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
4225+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
4226+ * IN THE SOFTWARE.
4227+ *
4228+ * Authors:
4229+ * Eric Anholt <eric@anholt.net>
4230+ * Keith Packard <keithp@keithp.com>
4231+ *
4232+ */
4233+
4234+#include "drmP.h"
4235+#include "drm.h"
4236+#include "i915_drm.h"
4237+#include "i915_drv.h"
4238+
4239+static int i915_gem_active_info(char *buf, char **start, off_t offset,
4240+ int request, int *eof, void *data)
4241+{
4242+ struct drm_minor *minor = (struct drm_minor *) data;
4243+ struct drm_device *dev = minor->dev;
4244+ drm_i915_private_t *dev_priv = dev->dev_private;
4245+ struct drm_i915_gem_object *obj_priv;
4246+ int len = 0;
4247+
4248+ if (offset > DRM_PROC_LIMIT) {
4249+ *eof = 1;
4250+ return 0;
4251+ }
4252+
4253+ *start = &buf[offset];
4254+ *eof = 0;
4255+ DRM_PROC_PRINT("Active:\n");
4256+ list_for_each_entry(obj_priv, &dev_priv->mm.active_list,
4257+ list)
4258+ {
4259+ struct drm_gem_object *obj = obj_priv->obj;
4260+ if (obj->name) {
4261+ DRM_PROC_PRINT(" %p(%d): %08x %08x %d\n",
4262+ obj, obj->name,
4263+ obj->read_domains, obj->write_domain,
4264+ obj_priv->last_rendering_seqno);
4265+ } else {
4266+ DRM_PROC_PRINT(" %p: %08x %08x %d\n",
4267+ obj,
4268+ obj->read_domains, obj->write_domain,
4269+ obj_priv->last_rendering_seqno);
4270+ }
4271+ }
4272+ if (len > request + offset)
4273+ return request;
4274+ *eof = 1;
4275+ return len - offset;
4276+}
4277+
4278+static int i915_gem_flushing_info(char *buf, char **start, off_t offset,
4279+ int request, int *eof, void *data)
4280+{
4281+ struct drm_minor *minor = (struct drm_minor *) data;
4282+ struct drm_device *dev = minor->dev;
4283+ drm_i915_private_t *dev_priv = dev->dev_private;
4284+ struct drm_i915_gem_object *obj_priv;
4285+ int len = 0;
4286+
4287+ if (offset > DRM_PROC_LIMIT) {
4288+ *eof = 1;
4289+ return 0;
4290+ }
4291+
4292+ *start = &buf[offset];
4293+ *eof = 0;
4294+ DRM_PROC_PRINT("Flushing:\n");
4295+ list_for_each_entry(obj_priv, &dev_priv->mm.flushing_list,
4296+ list)
4297+ {
4298+ struct drm_gem_object *obj = obj_priv->obj;
4299+ if (obj->name) {
4300+ DRM_PROC_PRINT(" %p(%d): %08x %08x %d\n",
4301+ obj, obj->name,
4302+ obj->read_domains, obj->write_domain,
4303+ obj_priv->last_rendering_seqno);
4304+ } else {
4305+ DRM_PROC_PRINT(" %p: %08x %08x %d\n", obj,
4306+ obj->read_domains, obj->write_domain,
4307+ obj_priv->last_rendering_seqno);
4308+ }
4309+ }
4310+ if (len > request + offset)
4311+ return request;
4312+ *eof = 1;
4313+ return len - offset;
4314+}
4315+
4316+static int i915_gem_inactive_info(char *buf, char **start, off_t offset,
4317+ int request, int *eof, void *data)
4318+{
4319+ struct drm_minor *minor = (struct drm_minor *) data;
4320+ struct drm_device *dev = minor->dev;
4321+ drm_i915_private_t *dev_priv = dev->dev_private;
4322+ struct drm_i915_gem_object *obj_priv;
4323+ int len = 0;
4324+
4325+ if (offset > DRM_PROC_LIMIT) {
4326+ *eof = 1;
4327+ return 0;
4328+ }
4329+
4330+ *start = &buf[offset];
4331+ *eof = 0;
4332+ DRM_PROC_PRINT("Inactive:\n");
4333+ list_for_each_entry(obj_priv, &dev_priv->mm.inactive_list,
4334+ list)
4335+ {
4336+ struct drm_gem_object *obj = obj_priv->obj;
4337+ if (obj->name) {
4338+ DRM_PROC_PRINT(" %p(%d): %08x %08x %d\n",
4339+ obj, obj->name,
4340+ obj->read_domains, obj->write_domain,
4341+ obj_priv->last_rendering_seqno);
4342+ } else {
4343+ DRM_PROC_PRINT(" %p: %08x %08x %d\n", obj,
4344+ obj->read_domains, obj->write_domain,
4345+ obj_priv->last_rendering_seqno);
4346+ }
4347+ }
4348+ if (len > request + offset)
4349+ return request;
4350+ *eof = 1;
4351+ return len - offset;
4352+}
4353+
4354+static int i915_gem_request_info(char *buf, char **start, off_t offset,
4355+ int request, int *eof, void *data)
4356+{
4357+ struct drm_minor *minor = (struct drm_minor *) data;
4358+ struct drm_device *dev = minor->dev;
4359+ drm_i915_private_t *dev_priv = dev->dev_private;
4360+ struct drm_i915_gem_request *gem_request;
4361+ int len = 0;
4362+
4363+ if (offset > DRM_PROC_LIMIT) {
4364+ *eof = 1;
4365+ return 0;
4366+ }
4367+
4368+ *start = &buf[offset];
4369+ *eof = 0;
4370+ DRM_PROC_PRINT("Request:\n");
4371+ list_for_each_entry(gem_request, &dev_priv->mm.request_list,
4372+ list)
4373+ {
4374+ DRM_PROC_PRINT(" %d @ %d %08x\n",
4375+ gem_request->seqno,
4376+ (int) (jiffies - gem_request->emitted_jiffies),
4377+ gem_request->flush_domains);
4378+ }
4379+ if (len > request + offset)
4380+ return request;
4381+ *eof = 1;
4382+ return len - offset;
4383+}
4384+
4385+static int i915_gem_seqno_info(char *buf, char **start, off_t offset,
4386+ int request, int *eof, void *data)
4387+{
4388+ struct drm_minor *minor = (struct drm_minor *) data;
4389+ struct drm_device *dev = minor->dev;
4390+ drm_i915_private_t *dev_priv = dev->dev_private;
4391+ int len = 0;
4392+
4393+ if (offset > DRM_PROC_LIMIT) {
4394+ *eof = 1;
4395+ return 0;
4396+ }
4397+
4398+ *start = &buf[offset];
4399+ *eof = 0;
4400+ DRM_PROC_PRINT("Current sequence: %d\n", i915_get_gem_seqno(dev));
4401+ DRM_PROC_PRINT("Waiter sequence: %d\n",
4402+ dev_priv->mm.waiting_gem_seqno);
4403+ DRM_PROC_PRINT("IRQ sequence: %d\n", dev_priv->mm.irq_gem_seqno);
4404+ if (len > request + offset)
4405+ return request;
4406+ *eof = 1;
4407+ return len - offset;
4408+}
4409+
4410+
4411+static int i915_interrupt_info(char *buf, char **start, off_t offset,
4412+ int request, int *eof, void *data)
4413+{
4414+ struct drm_minor *minor = (struct drm_minor *) data;
4415+ struct drm_device *dev = minor->dev;
4416+ drm_i915_private_t *dev_priv = dev->dev_private;
4417+ int len = 0;
4418+
4419+ if (offset > DRM_PROC_LIMIT) {
4420+ *eof = 1;
4421+ return 0;
4422+ }
4423+
4424+ *start = &buf[offset];
4425+ *eof = 0;
4426+ DRM_PROC_PRINT("Interrupt enable: %08x\n",
4427+ I915_READ(IER));
4428+ DRM_PROC_PRINT("Interrupt identity: %08x\n",
4429+ I915_READ(IIR));
4430+ DRM_PROC_PRINT("Interrupt mask: %08x\n",
4431+ I915_READ(IMR));
4432+ DRM_PROC_PRINT("Pipe A stat: %08x\n",
4433+ I915_READ(PIPEASTAT));
4434+ DRM_PROC_PRINT("Pipe B stat: %08x\n",
4435+ I915_READ(PIPEBSTAT));
4436+ DRM_PROC_PRINT("Interrupts received: %d\n",
4437+ atomic_read(&dev_priv->irq_received));
4438+ DRM_PROC_PRINT("Current sequence: %d\n",
4439+ i915_get_gem_seqno(dev));
4440+ DRM_PROC_PRINT("Waiter sequence: %d\n",
4441+ dev_priv->mm.waiting_gem_seqno);
4442+ DRM_PROC_PRINT("IRQ sequence: %d\n",
4443+ dev_priv->mm.irq_gem_seqno);
4444+ if (len > request + offset)
4445+ return request;
4446+ *eof = 1;
4447+ return len - offset;
4448+}
4449+
4450+static struct drm_proc_list {
4451+ /** file name */
4452+ const char *name;
4453+ /** proc callback*/
4454+ int (*f) (char *, char **, off_t, int, int *, void *);
4455+} i915_gem_proc_list[] = {
4456+ {"i915_gem_active", i915_gem_active_info},
4457+ {"i915_gem_flushing", i915_gem_flushing_info},
4458+ {"i915_gem_inactive", i915_gem_inactive_info},
4459+ {"i915_gem_request", i915_gem_request_info},
4460+ {"i915_gem_seqno", i915_gem_seqno_info},
4461+ {"i915_gem_interrupt", i915_interrupt_info},
4462+};
4463+
4464+#define I915_GEM_PROC_ENTRIES ARRAY_SIZE(i915_gem_proc_list)
4465+
4466+int i915_gem_proc_init(struct drm_minor *minor)
4467+{
4468+ struct proc_dir_entry *ent;
4469+ int i, j;
4470+
4471+ for (i = 0; i < I915_GEM_PROC_ENTRIES; i++) {
4472+ ent = create_proc_entry(i915_gem_proc_list[i].name,
4473+ S_IFREG | S_IRUGO, minor->dev_root);
4474+ if (!ent) {
4475+ DRM_ERROR("Cannot create /proc/dri/.../%s\n",
4476+ i915_gem_proc_list[i].name);
4477+ for (j = 0; j < i; j++)
4478+ remove_proc_entry(i915_gem_proc_list[i].name,
4479+ minor->dev_root);
4480+ return -1;
4481+ }
4482+ ent->read_proc = i915_gem_proc_list[i].f;
4483+ ent->data = minor;
4484+ }
4485+ return 0;
4486+}
4487+
4488+void i915_gem_proc_cleanup(struct drm_minor *minor)
4489+{
4490+ int i;
4491+
4492+ if (!minor->dev_root)
4493+ return;
4494+
4495+ for (i = 0; i < I915_GEM_PROC_ENTRIES; i++)
4496+ remove_proc_entry(i915_gem_proc_list[i].name, minor->dev_root);
4497+}
4498diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c
4499new file mode 100644
4500index 0000000..0c1b3a0
4501--- /dev/null
4502+++ b/drivers/gpu/drm/i915/i915_gem_tiling.c
4503@@ -0,0 +1,256 @@
4504+/*
4505+ * Copyright © 2008 Intel Corporation
4506+ *
4507+ * Permission is hereby granted, free of charge, to any person obtaining a
4508+ * copy of this software and associated documentation files (the "Software"),
4509+ * to deal in the Software without restriction, including without limitation
4510+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
4511+ * and/or sell copies of the Software, and to permit persons to whom the
4512+ * Software is furnished to do so, subject to the following conditions:
4513+ *
4514+ * The above copyright notice and this permission notice (including the next
4515+ * paragraph) shall be included in all copies or substantial portions of the
4516+ * Software.
4517+ *
4518+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
4519+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
4520+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
4521+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
4522+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
4523+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
4524+ * IN THE SOFTWARE.
4525+ *
4526+ * Authors:
4527+ * Eric Anholt <eric@anholt.net>
4528+ *
4529+ */
4530+
4531+#include "drmP.h"
4532+#include "drm.h"
4533+#include "i915_drm.h"
4534+#include "i915_drv.h"
4535+
4536+/** @file i915_gem_tiling.c
4537+ *
4538+ * Support for managing tiling state of buffer objects.
4539+ *
4540+ * The idea behind tiling is to increase cache hit rates by rearranging
4541+ * pixel data so that a group of pixel accesses are in the same cacheline.
4542+ * Performance improvement from doing this on the back/depth buffer are on
4543+ * the order of 30%.
4544+ *
4545+ * Intel architectures make this somewhat more complicated, though, by
4546+ * adjustments made to addressing of data when the memory is in interleaved
4547+ * mode (matched pairs of DIMMS) to improve memory bandwidth.
4548+ * For interleaved memory, the CPU sends every sequential 64 bytes
4549+ * to an alternate memory channel so it can get the bandwidth from both.
4550+ *
4551+ * The GPU also rearranges its accesses for increased bandwidth to interleaved
4552+ * memory, and it matches what the CPU does for non-tiled. However, when tiled
4553+ * it does it a little differently, since one walks addresses not just in the
4554+ * X direction but also Y. So, along with alternating channels when bit
4555+ * 6 of the address flips, it also alternates when other bits flip -- Bits 9
4556+ * (every 512 bytes, an X tile scanline) and 10 (every two X tile scanlines)
4557+ * are common to both the 915 and 965-class hardware.
4558+ *
4559+ * The CPU also sometimes XORs in higher bits as well, to improve
4560+ * bandwidth doing strided access like we do so frequently in graphics. This
4561+ * is called "Channel XOR Randomization" in the MCH documentation. The result
4562+ * is that the CPU is XORing in either bit 11 or bit 17 to bit 6 of its address
4563+ * decode.
4564+ *
4565+ * All of this bit 6 XORing has an effect on our memory management,
4566+ * as we need to make sure that the 3d driver can correctly address object
4567+ * contents.
4568+ *
4569+ * If we don't have interleaved memory, all tiling is safe and no swizzling is
4570+ * required.
4571+ *
4572+ * When bit 17 is XORed in, we simply refuse to tile at all. Bit
4573+ * 17 is not just a page offset, so as we page an objet out and back in,
4574+ * individual pages in it will have different bit 17 addresses, resulting in
4575+ * each 64 bytes being swapped with its neighbor!
4576+ *
4577+ * Otherwise, if interleaved, we have to tell the 3d driver what the address
4578+ * swizzling it needs to do is, since it's writing with the CPU to the pages
4579+ * (bit 6 and potentially bit 11 XORed in), and the GPU is reading from the
4580+ * pages (bit 6, 9, and 10 XORed in), resulting in a cumulative bit swizzling
4581+ * required by the CPU of XORing in bit 6, 9, 10, and potentially 11, in order
4582+ * to match what the GPU expects.
4583+ */
4584+
4585+/**
4586+ * Detects bit 6 swizzling of address lookup between IGD access and CPU
4587+ * access through main memory.
4588+ */
4589+void
4590+i915_gem_detect_bit_6_swizzle(struct drm_device *dev)
4591+{
4592+ drm_i915_private_t *dev_priv = dev->dev_private;
4593+ uint32_t swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN;
4594+ uint32_t swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN;
4595+
4596+ if (!IS_I9XX(dev)) {
4597+ /* As far as we know, the 865 doesn't have these bit 6
4598+ * swizzling issues.
4599+ */
4600+ swizzle_x = I915_BIT_6_SWIZZLE_NONE;
4601+ swizzle_y = I915_BIT_6_SWIZZLE_NONE;
4602+ } else if (!IS_I965G(dev) || IS_I965GM(dev)) {
4603+ uint32_t dcc;
4604+
4605+ /* On 915-945 and GM965, channel interleave by the CPU is
4606+ * determined by DCC. The CPU will alternate based on bit 6
4607+ * in interleaved mode, and the GPU will then also alternate
4608+ * on bit 6, 9, and 10 for X, but the CPU may also optionally
4609+ * alternate based on bit 17 (XOR not disabled and XOR
4610+ * bit == 17).
4611+ */
4612+ dcc = I915_READ(DCC);
4613+ switch (dcc & DCC_ADDRESSING_MODE_MASK) {
4614+ case DCC_ADDRESSING_MODE_SINGLE_CHANNEL:
4615+ case DCC_ADDRESSING_MODE_DUAL_CHANNEL_ASYMMETRIC:
4616+ swizzle_x = I915_BIT_6_SWIZZLE_NONE;
4617+ swizzle_y = I915_BIT_6_SWIZZLE_NONE;
4618+ break;
4619+ case DCC_ADDRESSING_MODE_DUAL_CHANNEL_INTERLEAVED:
4620+ if (IS_I915G(dev) || IS_I915GM(dev) ||
4621+ dcc & DCC_CHANNEL_XOR_DISABLE) {
4622+ swizzle_x = I915_BIT_6_SWIZZLE_9_10;
4623+ swizzle_y = I915_BIT_6_SWIZZLE_9;
4624+ } else if (IS_I965GM(dev)) {
4625+ /* GM965 only does bit 11-based channel
4626+ * randomization
4627+ */
4628+ swizzle_x = I915_BIT_6_SWIZZLE_9_10_11;
4629+ swizzle_y = I915_BIT_6_SWIZZLE_9_11;
4630+ } else {
4631+ /* Bit 17 or perhaps other swizzling */
4632+ swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN;
4633+ swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN;
4634+ }
4635+ break;
4636+ }
4637+ if (dcc == 0xffffffff) {
4638+ DRM_ERROR("Couldn't read from MCHBAR. "
4639+ "Disabling tiling.\n");
4640+ swizzle_x = I915_BIT_6_SWIZZLE_UNKNOWN;
4641+ swizzle_y = I915_BIT_6_SWIZZLE_UNKNOWN;
4642+ }
4643+ } else {
4644+ /* The 965, G33, and newer, have a very flexible memory
4645+ * configuration. It will enable dual-channel mode
4646+ * (interleaving) on as much memory as it can, and the GPU
4647+ * will additionally sometimes enable different bit 6
4648+ * swizzling for tiled objects from the CPU.
4649+ *
4650+ * Here's what I found on the G965:
4651+ * slot fill memory size swizzling
4652+ * 0A 0B 1A 1B 1-ch 2-ch
4653+ * 512 0 0 0 512 0 O
4654+ * 512 0 512 0 16 1008 X
4655+ * 512 0 0 512 16 1008 X
4656+ * 0 512 0 512 16 1008 X
4657+ * 1024 1024 1024 0 2048 1024 O
4658+ *
4659+ * We could probably detect this based on either the DRB
4660+ * matching, which was the case for the swizzling required in
4661+ * the table above, or from the 1-ch value being less than
4662+ * the minimum size of a rank.
4663+ */
4664+ if (I915_READ16(C0DRB3) != I915_READ16(C1DRB3)) {
4665+ swizzle_x = I915_BIT_6_SWIZZLE_NONE;
4666+ swizzle_y = I915_BIT_6_SWIZZLE_NONE;
4667+ } else {
4668+ swizzle_x = I915_BIT_6_SWIZZLE_9_10;
4669+ swizzle_y = I915_BIT_6_SWIZZLE_9;
4670+ }
4671+ }
4672+
4673+ dev_priv->mm.bit_6_swizzle_x = swizzle_x;
4674+ dev_priv->mm.bit_6_swizzle_y = swizzle_y;
4675+}
4676+
4677+/**
4678+ * Sets the tiling mode of an object, returning the required swizzling of
4679+ * bit 6 of addresses in the object.
4680+ */
4681+int
4682+i915_gem_set_tiling(struct drm_device *dev, void *data,
4683+ struct drm_file *file_priv)
4684+{
4685+ struct drm_i915_gem_set_tiling *args = data;
4686+ drm_i915_private_t *dev_priv = dev->dev_private;
4687+ struct drm_gem_object *obj;
4688+ struct drm_i915_gem_object *obj_priv;
4689+
4690+ obj = drm_gem_object_lookup(dev, file_priv, args->handle);
4691+ if (obj == NULL)
4692+ return -EINVAL;
4693+ obj_priv = obj->driver_private;
4694+
4695+ mutex_lock(&dev->struct_mutex);
4696+
4697+ if (args->tiling_mode == I915_TILING_NONE) {
4698+ obj_priv->tiling_mode = I915_TILING_NONE;
4699+ args->swizzle_mode = I915_BIT_6_SWIZZLE_NONE;
4700+ } else {
4701+ if (args->tiling_mode == I915_TILING_X)
4702+ args->swizzle_mode = dev_priv->mm.bit_6_swizzle_x;
4703+ else
4704+ args->swizzle_mode = dev_priv->mm.bit_6_swizzle_y;
4705+ /* If we can't handle the swizzling, make it untiled. */
4706+ if (args->swizzle_mode == I915_BIT_6_SWIZZLE_UNKNOWN) {
4707+ args->tiling_mode = I915_TILING_NONE;
4708+ args->swizzle_mode = I915_BIT_6_SWIZZLE_NONE;
4709+ }
4710+ }
4711+ obj_priv->tiling_mode = args->tiling_mode;
4712+
4713+ mutex_unlock(&dev->struct_mutex);
4714+
4715+ drm_gem_object_unreference(obj);
4716+
4717+ return 0;
4718+}
4719+
4720+/**
4721+ * Returns the current tiling mode and required bit 6 swizzling for the object.
4722+ */
4723+int
4724+i915_gem_get_tiling(struct drm_device *dev, void *data,
4725+ struct drm_file *file_priv)
4726+{
4727+ struct drm_i915_gem_get_tiling *args = data;
4728+ drm_i915_private_t *dev_priv = dev->dev_private;
4729+ struct drm_gem_object *obj;
4730+ struct drm_i915_gem_object *obj_priv;
4731+
4732+ obj = drm_gem_object_lookup(dev, file_priv, args->handle);
4733+ if (obj == NULL)
4734+ return -EINVAL;
4735+ obj_priv = obj->driver_private;
4736+
4737+ mutex_lock(&dev->struct_mutex);
4738+
4739+ args->tiling_mode = obj_priv->tiling_mode;
4740+ switch (obj_priv->tiling_mode) {
4741+ case I915_TILING_X:
4742+ args->swizzle_mode = dev_priv->mm.bit_6_swizzle_x;
4743+ break;
4744+ case I915_TILING_Y:
4745+ args->swizzle_mode = dev_priv->mm.bit_6_swizzle_y;
4746+ break;
4747+ case I915_TILING_NONE:
4748+ args->swizzle_mode = I915_BIT_6_SWIZZLE_NONE;
4749+ break;
4750+ default:
4751+ DRM_ERROR("unknown tiling mode\n");
4752+ }
4753+
4754+ mutex_unlock(&dev->struct_mutex);
4755+
4756+ drm_gem_object_unreference(obj);
4757+
4758+ return 0;
4759+}
4760diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
4761index f875959..f295bdf 100644
4762--- a/drivers/gpu/drm/i915/i915_irq.c
4763+++ b/drivers/gpu/drm/i915/i915_irq.c
4764@@ -407,15 +407,20 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
4765 I915_WRITE(PIPEBSTAT, pipeb_stats);
4766 }
4767
4768- if (iir & I915_ASLE_INTERRUPT)
4769- opregion_asle_intr(dev);
4770+ I915_WRITE(IIR, iir);
4771+ if (dev->pdev->msi_enabled)
4772+ I915_WRITE(IMR, dev_priv->irq_mask_reg);
4773+ (void) I915_READ(IIR); /* Flush posted writes */
4774
4775 dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
4776
4777- if (dev->pdev->msi_enabled)
4778- I915_WRITE(IMR, dev_priv->irq_mask_reg);
4779- I915_WRITE(IIR, iir);
4780- (void) I915_READ(IIR);
4781+ if (iir & I915_USER_INTERRUPT) {
4782+ dev_priv->mm.irq_gem_seqno = i915_get_gem_seqno(dev);
4783+ DRM_WAKEUP(&dev_priv->irq_queue);
4784+ }
4785+
4786+ if (iir & I915_ASLE_INTERRUPT)
4787+ opregion_asle_intr(dev);
4788
4789 if (vblank && dev_priv->swaps_pending > 0)
4790 drm_locked_tasklet(dev, i915_vblank_tasklet);
4791@@ -449,7 +454,7 @@ static int i915_emit_irq(struct drm_device * dev)
4792 return dev_priv->counter;
4793 }
4794
4795-static void i915_user_irq_get(struct drm_device *dev)
4796+void i915_user_irq_get(struct drm_device *dev)
4797 {
4798 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
4799
4800diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
4801index 43ad2cb..5c2d9f2 100644
4802--- a/drivers/gpu/drm/i915/i915_reg.h
4803+++ b/drivers/gpu/drm/i915/i915_reg.h
4804@@ -25,19 +25,6 @@
4805 #ifndef _I915_REG_H_
4806 #define _I915_REG_H_
4807
4808-/* MCH MMIO space */
4809-/** 915-945 and GM965 MCH register controlling DRAM channel access */
4810-#define DCC 0x200
4811-#define DCC_ADDRESSING_MODE_SINGLE_CHANNEL (0 << 0)
4812-#define DCC_ADDRESSING_MODE_DUAL_CHANNEL_ASYMMETRIC (1 << 0)
4813-#define DCC_ADDRESSING_MODE_DUAL_CHANNEL_INTERLEAVED (2 << 0)
4814-#define DCC_ADDRESSING_MODE_MASK (3 << 0)
4815-#define DCC_CHANNEL_XOR_DISABLE (1 << 10)
4816-
4817-/** 965 MCH register controlling DRAM channel configuration */
4818-#define CHDECMISC 0x111
4819-#define CHDECMISC_FLEXMEMORY (1 << 1)
4820-
4821 /*
4822 * The Bridge device's PCI config space has information about the
4823 * fb aperture size and the amount of pre-reserved memory.
4824@@ -516,6 +503,30 @@
4825 #define PALETTE_A 0x0a000
4826 #define PALETTE_B 0x0a800
4827
4828+/* MCH MMIO space */
4829+
4830+/*
4831+ * MCHBAR mirror.
4832+ *
4833+ * This mirrors the MCHBAR MMIO space whose location is determined by
4834+ * device 0 function 0's pci config register 0x44 or 0x48 and matches it in
4835+ * every way. It is not accessible from the CP register read instructions.
4836+ *
4837+ */
4838+#define MCHBAR_MIRROR_BASE 0x10000
4839+
4840+/** 915-945 and GM965 MCH register controlling DRAM channel access */
4841+#define DCC 0x10200
4842+#define DCC_ADDRESSING_MODE_SINGLE_CHANNEL (0 << 0)
4843+#define DCC_ADDRESSING_MODE_DUAL_CHANNEL_ASYMMETRIC (1 << 0)
4844+#define DCC_ADDRESSING_MODE_DUAL_CHANNEL_INTERLEAVED (2 << 0)
4845+#define DCC_ADDRESSING_MODE_MASK (3 << 0)
4846+#define DCC_CHANNEL_XOR_DISABLE (1 << 10)
4847+
4848+/** 965 MCH register controlling DRAM channel configuration */
4849+#define C0DRB3 0x10206
4850+#define C1DRB3 0x10606
4851+
4852 /*
4853 * Overlay regs
4854 */
4855diff --git a/include/drm/drm.h b/include/drm/drm.h
4856index 15e5503..f46ba4b 100644
4857--- a/include/drm/drm.h
4858+++ b/include/drm/drm.h
4859@@ -570,6 +570,34 @@ struct drm_set_version {
4860 int drm_dd_minor;
4861 };
4862
4863+/** DRM_IOCTL_GEM_CLOSE ioctl argument type */
4864+struct drm_gem_close {
4865+ /** Handle of the object to be closed. */
4866+ uint32_t handle;
4867+ uint32_t pad;
4868+};
4869+
4870+/** DRM_IOCTL_GEM_FLINK ioctl argument type */
4871+struct drm_gem_flink {
4872+ /** Handle for the object being named */
4873+ uint32_t handle;
4874+
4875+ /** Returned global name */
4876+ uint32_t name;
4877+};
4878+
4879+/** DRM_IOCTL_GEM_OPEN ioctl argument type */
4880+struct drm_gem_open {
4881+ /** Name of object being opened */
4882+ uint32_t name;
4883+
4884+ /** Returned handle for the object */
4885+ uint32_t handle;
4886+
4887+ /** Returned size of the object */
4888+ uint64_t size;
4889+};
4890+
4891 #define DRM_IOCTL_BASE 'd'
4892 #define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr)
4893 #define DRM_IOR(nr,type) _IOR(DRM_IOCTL_BASE,nr,type)
4894@@ -585,6 +613,9 @@ struct drm_set_version {
4895 #define DRM_IOCTL_GET_STATS DRM_IOR( 0x06, struct drm_stats)
4896 #define DRM_IOCTL_SET_VERSION DRM_IOWR(0x07, struct drm_set_version)
4897 #define DRM_IOCTL_MODESET_CTL DRM_IOW(0x08, struct drm_modeset_ctl)
4898+#define DRM_IOCTL_GEM_CLOSE DRM_IOW (0x09, struct drm_gem_close)
4899+#define DRM_IOCTL_GEM_FLINK DRM_IOWR(0x0a, struct drm_gem_flink)
4900+#define DRM_IOCTL_GEM_OPEN DRM_IOWR(0x0b, struct drm_gem_open)
4901
4902 #define DRM_IOCTL_SET_UNIQUE DRM_IOW( 0x10, struct drm_unique)
4903 #define DRM_IOCTL_AUTH_MAGIC DRM_IOW( 0x11, struct drm_auth)
4904diff --git a/include/drm/drmP.h b/include/drm/drmP.h
4905index e79ce07..1469a1b 100644
4906--- a/include/drm/drmP.h
4907+++ b/include/drm/drmP.h
4908@@ -104,6 +104,7 @@ struct drm_device;
4909 #define DRIVER_DMA_QUEUE 0x200
4910 #define DRIVER_FB_DMA 0x400
4911 #define DRIVER_IRQ_VBL2 0x800
4912+#define DRIVER_GEM 0x1000
4913
4914 /***********************************************************************/
4915 /** \name Begin the DRM... */
4916@@ -387,6 +388,10 @@ struct drm_file {
4917 struct drm_minor *minor;
4918 int remove_auth_on_close;
4919 unsigned long lock_count;
4920+ /** Mapping of mm object handles to object pointers. */
4921+ struct idr object_idr;
4922+ /** Lock for synchronization of access to object_idr. */
4923+ spinlock_t table_lock;
4924 struct file *filp;
4925 void *driver_priv;
4926 };
4927@@ -558,6 +563,56 @@ struct drm_ati_pcigart_info {
4928 };
4929
4930 /**
4931+ * This structure defines the drm_mm memory object, which will be used by the
4932+ * DRM for its buffer objects.
4933+ */
4934+struct drm_gem_object {
4935+ /** Reference count of this object */
4936+ struct kref refcount;
4937+
4938+ /** Handle count of this object. Each handle also holds a reference */
4939+ struct kref handlecount;
4940+
4941+ /** Related drm device */
4942+ struct drm_device *dev;
4943+
4944+ /** File representing the shmem storage */
4945+ struct file *filp;
4946+
4947+ /**
4948+ * Size of the object, in bytes. Immutable over the object's
4949+ * lifetime.
4950+ */
4951+ size_t size;
4952+
4953+ /**
4954+ * Global name for this object, starts at 1. 0 means unnamed.
4955+ * Access is covered by the object_name_lock in the related drm_device
4956+ */
4957+ int name;
4958+
4959+ /**
4960+ * Memory domains. These monitor which caches contain read/write data
4961+ * related to the object. When transitioning from one set of domains
4962+ * to another, the driver is called to ensure that caches are suitably
4963+ * flushed and invalidated
4964+ */
4965+ uint32_t read_domains;
4966+ uint32_t write_domain;
4967+
4968+ /**
4969+ * While validating an exec operation, the
4970+ * new read/write domain values are computed here.
4971+ * They will be transferred to the above values
4972+ * at the point that any cache flushing occurs
4973+ */
4974+ uint32_t pending_read_domains;
4975+ uint32_t pending_write_domain;
4976+
4977+ void *driver_private;
4978+};
4979+
4980+/**
4981 * DRM driver structure. This structure represent the common code for
4982 * a family of cards. There will one drm_device for each card present
4983 * in this family
4984@@ -657,6 +712,18 @@ struct drm_driver {
4985 void (*set_version) (struct drm_device *dev,
4986 struct drm_set_version *sv);
4987
4988+ int (*proc_init)(struct drm_minor *minor);
4989+ void (*proc_cleanup)(struct drm_minor *minor);
4990+
4991+ /**
4992+ * Driver-specific constructor for drm_gem_objects, to set up
4993+ * obj->driver_private.
4994+ *
4995+ * Returns 0 on success.
4996+ */
4997+ int (*gem_init_object) (struct drm_gem_object *obj);
4998+ void (*gem_free_object) (struct drm_gem_object *obj);
4999+
5000 int major;
5001 int minor;
5002 int patchlevel;
5003@@ -830,6 +897,22 @@ struct drm_device {
5004 spinlock_t drw_lock;
5005 struct idr drw_idr;
5006 /*@} */
5007+
5008+ /** \name GEM information */
5009+ /*@{ */
5010+ spinlock_t object_name_lock;
5011+ struct idr object_name_idr;
5012+ atomic_t object_count;
5013+ atomic_t object_memory;
5014+ atomic_t pin_count;
5015+ atomic_t pin_memory;
5016+ atomic_t gtt_count;
5017+ atomic_t gtt_memory;
5018+ uint32_t gtt_total;
5019+ uint32_t invalidate_domains; /* domains pending invalidation */
5020+ uint32_t flush_domains; /* domains pending flush */
5021+ /*@} */
5022+
5023 };
5024
5025 static __inline__ int drm_core_check_feature(struct drm_device *dev,
5026@@ -926,6 +1009,10 @@ extern void *drm_realloc(void *oldpt, size_t oldsize, size_t size, int area);
5027 extern DRM_AGP_MEM *drm_alloc_agp(struct drm_device *dev, int pages, u32 type);
5028 extern int drm_free_agp(DRM_AGP_MEM * handle, int pages);
5029 extern int drm_bind_agp(DRM_AGP_MEM * handle, unsigned int start);
5030+extern DRM_AGP_MEM *drm_agp_bind_pages(struct drm_device *dev,
5031+ struct page **pages,
5032+ unsigned long num_pages,
5033+ uint32_t gtt_offset);
5034 extern int drm_unbind_agp(DRM_AGP_MEM * handle);
5035
5036 /* Misc. IOCTL support (drm_ioctl.h) */
5037@@ -988,6 +1075,9 @@ extern int drm_getmagic(struct drm_device *dev, void *data,
5038 extern int drm_authmagic(struct drm_device *dev, void *data,
5039 struct drm_file *file_priv);
5040
5041+/* Cache management (drm_cache.c) */
5042+void drm_clflush_pages(struct page *pages[], unsigned long num_pages);
5043+
5044 /* Locking IOCTL support (drm_lock.h) */
5045 extern int drm_lock(struct drm_device *dev, void *data,
5046 struct drm_file *file_priv);
5047@@ -1094,6 +1184,7 @@ extern DRM_AGP_MEM *drm_agp_allocate_memory(struct agp_bridge_data *bridge, size
5048 extern int drm_agp_free_memory(DRM_AGP_MEM * handle);
5049 extern int drm_agp_bind_memory(DRM_AGP_MEM * handle, off_t start);
5050 extern int drm_agp_unbind_memory(DRM_AGP_MEM * handle);
5051+extern void drm_agp_chipset_flush(struct drm_device *dev);
5052
5053 /* Stub support (drm_stub.h) */
5054 extern int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
5055@@ -1156,6 +1247,66 @@ extern unsigned long drm_mm_tail_space(struct drm_mm *mm);
5056 extern int drm_mm_remove_space_from_tail(struct drm_mm *mm, unsigned long size);
5057 extern int drm_mm_add_space_to_tail(struct drm_mm *mm, unsigned long size);
5058
5059+/* Graphics Execution Manager library functions (drm_gem.c) */
5060+int drm_gem_init(struct drm_device *dev);
5061+void drm_gem_object_free(struct kref *kref);
5062+struct drm_gem_object *drm_gem_object_alloc(struct drm_device *dev,
5063+ size_t size);
5064+void drm_gem_object_handle_free(struct kref *kref);
5065+
5066+static inline void
5067+drm_gem_object_reference(struct drm_gem_object *obj)
5068+{
5069+ kref_get(&obj->refcount);
5070+}
5071+
5072+static inline void
5073+drm_gem_object_unreference(struct drm_gem_object *obj)
5074+{
5075+ if (obj == NULL)
5076+ return;
5077+
5078+ kref_put(&obj->refcount, drm_gem_object_free);
5079+}
5080+
5081+int drm_gem_handle_create(struct drm_file *file_priv,
5082+ struct drm_gem_object *obj,
5083+ int *handlep);
5084+
5085+static inline void
5086+drm_gem_object_handle_reference(struct drm_gem_object *obj)
5087+{
5088+ drm_gem_object_reference(obj);
5089+ kref_get(&obj->handlecount);
5090+}
5091+
5092+static inline void
5093+drm_gem_object_handle_unreference(struct drm_gem_object *obj)
5094+{
5095+ if (obj == NULL)
5096+ return;
5097+
5098+ /*
5099+ * Must bump handle count first as this may be the last
5100+ * ref, in which case the object would disappear before we
5101+ * checked for a name
5102+ */
5103+ kref_put(&obj->handlecount, drm_gem_object_handle_free);
5104+ drm_gem_object_unreference(obj);
5105+}
5106+
5107+struct drm_gem_object *drm_gem_object_lookup(struct drm_device *dev,
5108+ struct drm_file *filp,
5109+ int handle);
5110+int drm_gem_close_ioctl(struct drm_device *dev, void *data,
5111+ struct drm_file *file_priv);
5112+int drm_gem_flink_ioctl(struct drm_device *dev, void *data,
5113+ struct drm_file *file_priv);
5114+int drm_gem_open_ioctl(struct drm_device *dev, void *data,
5115+ struct drm_file *file_priv);
5116+void drm_gem_open(struct drm_device *dev, struct drm_file *file_private);
5117+void drm_gem_release(struct drm_device *dev, struct drm_file *file_private);
5118+
5119 extern void drm_core_ioremap(struct drm_map *map, struct drm_device *dev);
5120 extern void drm_core_ioremap_wc(struct drm_map *map, struct drm_device *dev);
5121 extern void drm_core_ioremapfree(struct drm_map *map, struct drm_device *dev);
5122diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h
5123index 05c66cf..59d08fc 100644
5124--- a/include/drm/i915_drm.h
5125+++ b/include/drm/i915_drm.h
5126@@ -143,6 +143,22 @@ typedef struct _drm_i915_sarea {
5127 #define DRM_I915_GET_VBLANK_PIPE 0x0e
5128 #define DRM_I915_VBLANK_SWAP 0x0f
5129 #define DRM_I915_HWS_ADDR 0x11
5130+#define DRM_I915_GEM_INIT 0x13
5131+#define DRM_I915_GEM_EXECBUFFER 0x14
5132+#define DRM_I915_GEM_PIN 0x15
5133+#define DRM_I915_GEM_UNPIN 0x16
5134+#define DRM_I915_GEM_BUSY 0x17
5135+#define DRM_I915_GEM_THROTTLE 0x18
5136+#define DRM_I915_GEM_ENTERVT 0x19
5137+#define DRM_I915_GEM_LEAVEVT 0x1a
5138+#define DRM_I915_GEM_CREATE 0x1b
5139+#define DRM_I915_GEM_PREAD 0x1c
5140+#define DRM_I915_GEM_PWRITE 0x1d
5141+#define DRM_I915_GEM_MMAP 0x1e
5142+#define DRM_I915_GEM_SET_DOMAIN 0x1f
5143+#define DRM_I915_GEM_SW_FINISH 0x20
5144+#define DRM_I915_GEM_SET_TILING 0x21
5145+#define DRM_I915_GEM_GET_TILING 0x22
5146
5147 #define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t)
5148 #define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH)
5149@@ -160,6 +176,20 @@ typedef struct _drm_i915_sarea {
5150 #define DRM_IOCTL_I915_SET_VBLANK_PIPE DRM_IOW( DRM_COMMAND_BASE + DRM_I915_SET_VBLANK_PIPE, drm_i915_vblank_pipe_t)
5151 #define DRM_IOCTL_I915_GET_VBLANK_PIPE DRM_IOR( DRM_COMMAND_BASE + DRM_I915_GET_VBLANK_PIPE, drm_i915_vblank_pipe_t)
5152 #define DRM_IOCTL_I915_VBLANK_SWAP DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_VBLANK_SWAP, drm_i915_vblank_swap_t)
5153+#define DRM_IOCTL_I915_GEM_PIN DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_PIN, struct drm_i915_gem_pin)
5154+#define DRM_IOCTL_I915_GEM_UNPIN DRM_IOW(DRM_COMMAND_BASE + DRM_I915_GEM_UNPIN, struct drm_i915_gem_unpin)
5155+#define DRM_IOCTL_I915_GEM_BUSY DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_BUSY, struct drm_i915_gem_busy)
5156+#define DRM_IOCTL_I915_GEM_THROTTLE DRM_IO ( DRM_COMMAND_BASE + DRM_I915_GEM_THROTTLE)
5157+#define DRM_IOCTL_I915_GEM_ENTERVT DRM_IO(DRM_COMMAND_BASE + DRM_I915_GEM_ENTERVT)
5158+#define DRM_IOCTL_I915_GEM_LEAVEVT DRM_IO(DRM_COMMAND_BASE + DRM_I915_GEM_LEAVEVT)
5159+#define DRM_IOCTL_I915_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_CREATE, struct drm_i915_gem_create)
5160+#define DRM_IOCTL_I915_GEM_PREAD DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_PREAD, struct drm_i915_gem_pread)
5161+#define DRM_IOCTL_I915_GEM_PWRITE DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_PWRITE, struct drm_i915_gem_pwrite)
5162+#define DRM_IOCTL_I915_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MMAP, struct drm_i915_gem_mmap)
5163+#define DRM_IOCTL_I915_GEM_SET_DOMAIN DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_SET_DOMAIN, struct drm_i915_gem_set_domain)
5164+#define DRM_IOCTL_I915_GEM_SW_FINISH DRM_IOW (DRM_COMMAND_BASE + DRM_I915_GEM_SW_FINISH, struct drm_i915_gem_sw_finish)
5165+#define DRM_IOCTL_I915_GEM_SET_TILING DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_SET_TILING, struct drm_i915_gem_set_tiling)
5166+#define DRM_IOCTL_I915_GEM_GET_TILING DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_GET_TILING, struct drm_i915_gem_get_tiling)
5167
5168 /* Allow drivers to submit batchbuffers directly to hardware, relying
5169 * on the security mechanisms provided by hardware.
5170@@ -200,6 +230,7 @@ typedef struct drm_i915_irq_wait {
5171 #define I915_PARAM_IRQ_ACTIVE 1
5172 #define I915_PARAM_ALLOW_BATCHBUFFER 2
5173 #define I915_PARAM_LAST_DISPATCH 3
5174+#define I915_PARAM_HAS_GEM 5
5175
5176 typedef struct drm_i915_getparam {
5177 int param;
5178@@ -267,4 +298,305 @@ typedef struct drm_i915_hws_addr {
5179 uint64_t addr;
5180 } drm_i915_hws_addr_t;
5181
5182+struct drm_i915_gem_init {
5183+ /**
5184+ * Beginning offset in the GTT to be managed by the DRM memory
5185+ * manager.
5186+ */
5187+ uint64_t gtt_start;
5188+ /**
5189+ * Ending offset in the GTT to be managed by the DRM memory
5190+ * manager.
5191+ */
5192+ uint64_t gtt_end;
5193+};
5194+
5195+struct drm_i915_gem_create {
5196+ /**
5197+ * Requested size for the object.
5198+ *
5199+ * The (page-aligned) allocated size for the object will be returned.
5200+ */
5201+ uint64_t size;
5202+ /**
5203+ * Returned handle for the object.
5204+ *
5205+ * Object handles are nonzero.
5206+ */
5207+ uint32_t handle;
5208+ uint32_t pad;
5209+};
5210+
5211+struct drm_i915_gem_pread {
5212+ /** Handle for the object being read. */
5213+ uint32_t handle;
5214+ uint32_t pad;
5215+ /** Offset into the object to read from */
5216+ uint64_t offset;
5217+ /** Length of data to read */
5218+ uint64_t size;
5219+ /**
5220+ * Pointer to write the data into.
5221+ *
5222+ * This is a fixed-size type for 32/64 compatibility.
5223+ */
5224+ uint64_t data_ptr;
5225+};
5226+
5227+struct drm_i915_gem_pwrite {
5228+ /** Handle for the object being written to. */
5229+ uint32_t handle;
5230+ uint32_t pad;
5231+ /** Offset into the object to write to */
5232+ uint64_t offset;
5233+ /** Length of data to write */
5234+ uint64_t size;
5235+ /**
5236+ * Pointer to read the data from.
5237+ *
5238+ * This is a fixed-size type for 32/64 compatibility.
5239+ */
5240+ uint64_t data_ptr;
5241+};
5242+
5243+struct drm_i915_gem_mmap {
5244+ /** Handle for the object being mapped. */
5245+ uint32_t handle;
5246+ uint32_t pad;
5247+ /** Offset in the object to map. */
5248+ uint64_t offset;
5249+ /**
5250+ * Length of data to map.
5251+ *
5252+ * The value will be page-aligned.
5253+ */
5254+ uint64_t size;
5255+ /**
5256+ * Returned pointer the data was mapped at.
5257+ *
5258+ * This is a fixed-size type for 32/64 compatibility.
5259+ */
5260+ uint64_t addr_ptr;
5261+};
5262+
5263+struct drm_i915_gem_set_domain {
5264+ /** Handle for the object */
5265+ uint32_t handle;
5266+
5267+ /** New read domains */
5268+ uint32_t read_domains;
5269+
5270+ /** New write domain */
5271+ uint32_t write_domain;
5272+};
5273+
5274+struct drm_i915_gem_sw_finish {
5275+ /** Handle for the object */
5276+ uint32_t handle;
5277+};
5278+
5279+struct drm_i915_gem_relocation_entry {
5280+ /**
5281+ * Handle of the buffer being pointed to by this relocation entry.
5282+ *
5283+ * It's appealing to make this be an index into the mm_validate_entry
5284+ * list to refer to the buffer, but this allows the driver to create
5285+ * a relocation list for state buffers and not re-write it per
5286+ * exec using the buffer.
5287+ */
5288+ uint32_t target_handle;
5289+
5290+ /**
5291+ * Value to be added to the offset of the target buffer to make up
5292+ * the relocation entry.
5293+ */
5294+ uint32_t delta;
5295+
5296+ /** Offset in the buffer the relocation entry will be written into */
5297+ uint64_t offset;
5298+
5299+ /**
5300+ * Offset value of the target buffer that the relocation entry was last
5301+ * written as.
5302+ *
5303+ * If the buffer has the same offset as last time, we can skip syncing
5304+ * and writing the relocation. This value is written back out by
5305+ * the execbuffer ioctl when the relocation is written.
5306+ */
5307+ uint64_t presumed_offset;
5308+
5309+ /**
5310+ * Target memory domains read by this operation.
5311+ */
5312+ uint32_t read_domains;
5313+
5314+ /**
5315+ * Target memory domains written by this operation.
5316+ *
5317+ * Note that only one domain may be written by the whole
5318+ * execbuffer operation, so that where there are conflicts,
5319+ * the application will get -EINVAL back.
5320+ */
5321+ uint32_t write_domain;
5322+};
5323+
5324+/** @{
5325+ * Intel memory domains
5326+ *
5327+ * Most of these just align with the various caches in
5328+ * the system and are used to flush and invalidate as
5329+ * objects end up cached in different domains.
5330+ */
5331+/** CPU cache */
5332+#define I915_GEM_DOMAIN_CPU 0x00000001
5333+/** Render cache, used by 2D and 3D drawing */
5334+#define I915_GEM_DOMAIN_RENDER 0x00000002
5335+/** Sampler cache, used by texture engine */
5336+#define I915_GEM_DOMAIN_SAMPLER 0x00000004
5337+/** Command queue, used to load batch buffers */
5338+#define I915_GEM_DOMAIN_COMMAND 0x00000008
5339+/** Instruction cache, used by shader programs */
5340+#define I915_GEM_DOMAIN_INSTRUCTION 0x00000010
5341+/** Vertex address cache */
5342+#define I915_GEM_DOMAIN_VERTEX 0x00000020
5343+/** GTT domain - aperture and scanout */
5344+#define I915_GEM_DOMAIN_GTT 0x00000040
5345+/** @} */
5346+
5347+struct drm_i915_gem_exec_object {
5348+ /**
5349+ * User's handle for a buffer to be bound into the GTT for this
5350+ * operation.
5351+ */
5352+ uint32_t handle;
5353+
5354+ /** Number of relocations to be performed on this buffer */
5355+ uint32_t relocation_count;
5356+ /**
5357+ * Pointer to array of struct drm_i915_gem_relocation_entry containing
5358+ * the relocations to be performed in this buffer.
5359+ */
5360+ uint64_t relocs_ptr;
5361+
5362+ /** Required alignment in graphics aperture */
5363+ uint64_t alignment;
5364+
5365+ /**
5366+ * Returned value of the updated offset of the object, for future
5367+ * presumed_offset writes.
5368+ */
5369+ uint64_t offset;
5370+};
5371+
5372+struct drm_i915_gem_execbuffer {
5373+ /**
5374+ * List of buffers to be validated with their relocations to be
5375+ * performend on them.
5376+ *
5377+ * This is a pointer to an array of struct drm_i915_gem_validate_entry.
5378+ *
5379+ * These buffers must be listed in an order such that all relocations
5380+ * a buffer is performing refer to buffers that have already appeared
5381+ * in the validate list.
5382+ */
5383+ uint64_t buffers_ptr;
5384+ uint32_t buffer_count;
5385+
5386+ /** Offset in the batchbuffer to start execution from. */
5387+ uint32_t batch_start_offset;
5388+ /** Bytes used in batchbuffer from batch_start_offset */
5389+ uint32_t batch_len;
5390+ uint32_t DR1;
5391+ uint32_t DR4;
5392+ uint32_t num_cliprects;
5393+ /** This is a struct drm_clip_rect *cliprects */
5394+ uint64_t cliprects_ptr;
5395+};
5396+
5397+struct drm_i915_gem_pin {
5398+ /** Handle of the buffer to be pinned. */
5399+ uint32_t handle;
5400+ uint32_t pad;
5401+
5402+ /** alignment required within the aperture */
5403+ uint64_t alignment;
5404+
5405+ /** Returned GTT offset of the buffer. */
5406+ uint64_t offset;
5407+};
5408+
5409+struct drm_i915_gem_unpin {
5410+ /** Handle of the buffer to be unpinned. */
5411+ uint32_t handle;
5412+ uint32_t pad;
5413+};
5414+
5415+struct drm_i915_gem_busy {
5416+ /** Handle of the buffer to check for busy */
5417+ uint32_t handle;
5418+
5419+ /** Return busy status (1 if busy, 0 if idle) */
5420+ uint32_t busy;
5421+};
5422+
5423+#define I915_TILING_NONE 0
5424+#define I915_TILING_X 1
5425+#define I915_TILING_Y 2
5426+
5427+#define I915_BIT_6_SWIZZLE_NONE 0
5428+#define I915_BIT_6_SWIZZLE_9 1
5429+#define I915_BIT_6_SWIZZLE_9_10 2
5430+#define I915_BIT_6_SWIZZLE_9_11 3
5431+#define I915_BIT_6_SWIZZLE_9_10_11 4
5432+/* Not seen by userland */
5433+#define I915_BIT_6_SWIZZLE_UNKNOWN 5
5434+
5435+struct drm_i915_gem_set_tiling {
5436+ /** Handle of the buffer to have its tiling state updated */
5437+ uint32_t handle;
5438+
5439+ /**
5440+ * Tiling mode for the object (I915_TILING_NONE, I915_TILING_X,
5441+ * I915_TILING_Y).
5442+ *
5443+ * This value is to be set on request, and will be updated by the
5444+ * kernel on successful return with the actual chosen tiling layout.
5445+ *
5446+ * The tiling mode may be demoted to I915_TILING_NONE when the system
5447+ * has bit 6 swizzling that can't be managed correctly by GEM.
5448+ *
5449+ * Buffer contents become undefined when changing tiling_mode.
5450+ */
5451+ uint32_t tiling_mode;
5452+
5453+ /**
5454+ * Stride in bytes for the object when in I915_TILING_X or
5455+ * I915_TILING_Y.
5456+ */
5457+ uint32_t stride;
5458+
5459+ /**
5460+ * Returned address bit 6 swizzling required for CPU access through
5461+ * mmap mapping.
5462+ */
5463+ uint32_t swizzle_mode;
5464+};
5465+
5466+struct drm_i915_gem_get_tiling {
5467+ /** Handle of the buffer to get tiling state for. */
5468+ uint32_t handle;
5469+
5470+ /**
5471+ * Current tiling mode for the object (I915_TILING_NONE, I915_TILING_X,
5472+ * I915_TILING_Y).
5473+ */
5474+ uint32_t tiling_mode;
5475+
5476+ /**
5477+ * Returned address bit 6 swizzling required for CPU access through
5478+ * mmap mapping.
5479+ */
5480+ uint32_t swizzle_mode;
5481+};
5482+
5483 #endif /* _I915_DRM_H_ */
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27/0015-i915-Add-chip-set-ID-param.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27/0015-i915-Add-chip-set-ID-param.patch
new file mode 100644
index 0000000000..c3bf8ebd13
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27/0015-i915-Add-chip-set-ID-param.patch
@@ -0,0 +1,35 @@
1commit 26ead293ddf664f33dc0ba12b726887c40ce3957
2Author: Kristian Høgsberg <krh@redhat.com>
3Date: Wed Aug 20 11:08:52 2008 -0400
4
5 i915: Add chip set ID param.
6
7 Signed-off-by: Kristian Høgsberg <krh@redhat.com>
8 Signed-off-by: Eric Anholt <eric@anholt.net>
9
10diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
11index 3b5aa74..205d21e 100644
12--- a/drivers/gpu/drm/i915/i915_dma.c
13+++ b/drivers/gpu/drm/i915/i915_dma.c
14@@ -689,6 +689,9 @@ static int i915_getparam(struct drm_device *dev, void *data,
15 case I915_PARAM_LAST_DISPATCH:
16 value = READ_BREADCRUMB(dev_priv);
17 break;
18+ case I915_PARAM_CHIPSET_ID:
19+ value = dev->pci_device;
20+ break;
21 case I915_PARAM_HAS_GEM:
22 value = 1;
23 break;
24diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h
25index 59d08fc..eb4b350 100644
26--- a/include/drm/i915_drm.h
27+++ b/include/drm/i915_drm.h
28@@ -230,6 +230,7 @@ typedef struct drm_i915_irq_wait {
29 #define I915_PARAM_IRQ_ACTIVE 1
30 #define I915_PARAM_ALLOW_BATCHBUFFER 2
31 #define I915_PARAM_LAST_DISPATCH 3
32+#define I915_PARAM_CHIPSET_ID 4
33 #define I915_PARAM_HAS_GEM 5
34
35 typedef struct drm_i915_getparam {
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27/0016-i915-Use-struct_mutex-to-protect-ring-in-GEM-mode.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27/0016-i915-Use-struct_mutex-to-protect-ring-in-GEM-mode.patch
new file mode 100644
index 0000000000..910f37e9c5
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27/0016-i915-Use-struct_mutex-to-protect-ring-in-GEM-mode.patch
@@ -0,0 +1,205 @@
1commit 8a524209fce67d3b6d2e831b5dad4eced796ce98
2Author: Eric Anholt <eric@anholt.net>
3Date: Mon Sep 1 16:45:29 2008 -0700
4
5 i915: Use struct_mutex to protect ring in GEM mode.
6
7 In the conversion for GEM, we had stopped using the hardware lock to protect
8 ring usage, since it was all internal to the DRM now. However, some paths
9 weren't converted to using struct_mutex to prevent multiple threads from
10 concurrently working on the ring, in particular between the vblank swap handler
11 and ioctls.
12
13 Signed-off-by: Eric Anholt <eric@anholt.net>
14
15diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
16index 205d21e..25f59c1 100644
17--- a/drivers/gpu/drm/i915/i915_dma.c
18+++ b/drivers/gpu/drm/i915/i915_dma.c
19@@ -588,9 +588,15 @@ static int i915_quiescent(struct drm_device * dev)
20 static int i915_flush_ioctl(struct drm_device *dev, void *data,
21 struct drm_file *file_priv)
22 {
23- LOCK_TEST_WITH_RETURN(dev, file_priv);
24+ int ret;
25+
26+ RING_LOCK_TEST_WITH_RETURN(dev, file_priv);
27
28- return i915_quiescent(dev);
29+ mutex_lock(&dev->struct_mutex);
30+ ret = i915_quiescent(dev);
31+ mutex_unlock(&dev->struct_mutex);
32+
33+ return ret;
34 }
35
36 static int i915_batchbuffer(struct drm_device *dev, void *data,
37@@ -611,14 +617,16 @@ static int i915_batchbuffer(struct drm_device *dev, void *data,
38 DRM_DEBUG("i915 batchbuffer, start %x used %d cliprects %d\n",
39 batch->start, batch->used, batch->num_cliprects);
40
41- LOCK_TEST_WITH_RETURN(dev, file_priv);
42+ RING_LOCK_TEST_WITH_RETURN(dev, file_priv);
43
44 if (batch->num_cliprects && DRM_VERIFYAREA_READ(batch->cliprects,
45 batch->num_cliprects *
46 sizeof(struct drm_clip_rect)))
47 return -EFAULT;
48
49+ mutex_lock(&dev->struct_mutex);
50 ret = i915_dispatch_batchbuffer(dev, batch);
51+ mutex_unlock(&dev->struct_mutex);
52
53 sarea_priv->last_dispatch = (int)hw_status[5];
54 return ret;
55@@ -637,7 +645,7 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data,
56 DRM_DEBUG("i915 cmdbuffer, buf %p sz %d cliprects %d\n",
57 cmdbuf->buf, cmdbuf->sz, cmdbuf->num_cliprects);
58
59- LOCK_TEST_WITH_RETURN(dev, file_priv);
60+ RING_LOCK_TEST_WITH_RETURN(dev, file_priv);
61
62 if (cmdbuf->num_cliprects &&
63 DRM_VERIFYAREA_READ(cmdbuf->cliprects,
64@@ -647,7 +655,9 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data,
65 return -EFAULT;
66 }
67
68+ mutex_lock(&dev->struct_mutex);
69 ret = i915_dispatch_cmdbuffer(dev, cmdbuf);
70+ mutex_unlock(&dev->struct_mutex);
71 if (ret) {
72 DRM_ERROR("i915_dispatch_cmdbuffer failed\n");
73 return ret;
74@@ -660,11 +670,17 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data,
75 static int i915_flip_bufs(struct drm_device *dev, void *data,
76 struct drm_file *file_priv)
77 {
78+ int ret;
79+
80 DRM_DEBUG("%s\n", __FUNCTION__);
81
82- LOCK_TEST_WITH_RETURN(dev, file_priv);
83+ RING_LOCK_TEST_WITH_RETURN(dev, file_priv);
84
85- return i915_dispatch_flip(dev);
86+ mutex_lock(&dev->struct_mutex);
87+ ret = i915_dispatch_flip(dev);
88+ mutex_unlock(&dev->struct_mutex);
89+
90+ return ret;
91 }
92
93 static int i915_getparam(struct drm_device *dev, void *data,
94diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
95index 87b071a..8547f0a 100644
96--- a/drivers/gpu/drm/i915/i915_drv.h
97+++ b/drivers/gpu/drm/i915/i915_drv.h
98@@ -285,6 +285,9 @@ typedef struct drm_i915_private {
99 */
100 struct delayed_work retire_work;
101
102+ /** Work task for vblank-related ring access */
103+ struct work_struct vblank_work;
104+
105 uint32_t next_gem_seqno;
106
107 /**
108@@ -435,6 +438,7 @@ extern int i915_irq_wait(struct drm_device *dev, void *data,
109 void i915_user_irq_get(struct drm_device *dev);
110 void i915_user_irq_put(struct drm_device *dev);
111
112+extern void i915_gem_vblank_work_handler(struct work_struct *work);
113 extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS);
114 extern void i915_driver_irq_preinstall(struct drm_device * dev);
115 extern int i915_driver_irq_postinstall(struct drm_device *dev);
116@@ -538,6 +542,17 @@ extern void intel_opregion_free(struct drm_device *dev);
117 extern void opregion_asle_intr(struct drm_device *dev);
118 extern void opregion_enable_asle(struct drm_device *dev);
119
120+/**
121+ * Lock test for when it's just for synchronization of ring access.
122+ *
123+ * In that case, we don't need to do it when GEM is initialized as nobody else
124+ * has access to the ring.
125+ */
126+#define RING_LOCK_TEST_WITH_RETURN(dev, file_priv) do { \
127+ if (((drm_i915_private_t *)dev->dev_private)->ring.ring_obj == NULL) \
128+ LOCK_TEST_WITH_RETURN(dev, file_priv); \
129+} while (0)
130+
131 #define I915_READ(reg) DRM_READ32(dev_priv->mmio_map, (reg))
132 #define I915_WRITE(reg,val) DRM_WRITE32(dev_priv->mmio_map, (reg), (val))
133 #define I915_READ16(reg) DRM_READ16(dev_priv->mmio_map, (reg))
134diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
135index 90ae8a0..bb6e5a3 100644
136--- a/drivers/gpu/drm/i915/i915_gem.c
137+++ b/drivers/gpu/drm/i915/i915_gem.c
138@@ -2491,6 +2491,8 @@ i915_gem_load(struct drm_device *dev)
139 INIT_LIST_HEAD(&dev_priv->mm.request_list);
140 INIT_DELAYED_WORK(&dev_priv->mm.retire_work,
141 i915_gem_retire_work_handler);
142+ INIT_WORK(&dev_priv->mm.vblank_work,
143+ i915_gem_vblank_work_handler);
144 dev_priv->mm.next_gem_seqno = 1;
145
146 i915_gem_detect_bit_6_swizzle(dev);
147diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
148index f295bdf..d04c526 100644
149--- a/drivers/gpu/drm/i915/i915_irq.c
150+++ b/drivers/gpu/drm/i915/i915_irq.c
151@@ -349,6 +349,21 @@ u32 i915_get_vblank_counter(struct drm_device *dev, int plane)
152 return count;
153 }
154
155+void
156+i915_gem_vblank_work_handler(struct work_struct *work)
157+{
158+ drm_i915_private_t *dev_priv;
159+ struct drm_device *dev;
160+
161+ dev_priv = container_of(work, drm_i915_private_t,
162+ mm.vblank_work);
163+ dev = dev_priv->dev;
164+
165+ mutex_lock(&dev->struct_mutex);
166+ i915_vblank_tasklet(dev);
167+ mutex_unlock(&dev->struct_mutex);
168+}
169+
170 irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
171 {
172 struct drm_device *dev = (struct drm_device *) arg;
173@@ -422,8 +437,12 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
174 if (iir & I915_ASLE_INTERRUPT)
175 opregion_asle_intr(dev);
176
177- if (vblank && dev_priv->swaps_pending > 0)
178- drm_locked_tasklet(dev, i915_vblank_tasklet);
179+ if (vblank && dev_priv->swaps_pending > 0) {
180+ if (dev_priv->ring.ring_obj == NULL)
181+ drm_locked_tasklet(dev, i915_vblank_tasklet);
182+ else
183+ schedule_work(&dev_priv->mm.vblank_work);
184+ }
185
186 return IRQ_HANDLED;
187 }
188@@ -514,14 +533,15 @@ int i915_irq_emit(struct drm_device *dev, void *data,
189 drm_i915_irq_emit_t *emit = data;
190 int result;
191
192- LOCK_TEST_WITH_RETURN(dev, file_priv);
193+ RING_LOCK_TEST_WITH_RETURN(dev, file_priv);
194
195 if (!dev_priv) {
196 DRM_ERROR("called with no initialization\n");
197 return -EINVAL;
198 }
199-
200+ mutex_lock(&dev->struct_mutex);
201 result = i915_emit_irq(dev);
202+ mutex_unlock(&dev->struct_mutex);
203
204 if (DRM_COPY_TO_USER(emit->irq_seq, &result, sizeof(int))) {
205 DRM_ERROR("copy_to_user\n");
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27/0017-i915-Make-use-of-sarea_priv-conditional.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27/0017-i915-Make-use-of-sarea_priv-conditional.patch
new file mode 100644
index 0000000000..542b69dd52
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27/0017-i915-Make-use-of-sarea_priv-conditional.patch
@@ -0,0 +1,147 @@
1commit 69749cf99189a8a78de201ac24990c91ee111469
2Author: Kristian Høgsberg <krh@redhat.com>
3Date: Wed Aug 20 11:20:13 2008 -0400
4
5 i915: Make use of sarea_priv conditional.
6
7 We fail ioctls that depend on the sarea_priv with EINVAL.
8
9 Signed-off-by: Kristian Høgsberg <krh@redhat.com>
10 Signed-off-by: Eric Anholt <eric@anholt.net>
11
12diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
13index 25f59c1..dbd3f49 100644
14--- a/drivers/gpu/drm/i915/i915_dma.c
15+++ b/drivers/gpu/drm/i915/i915_dma.c
16@@ -55,7 +55,8 @@ int i915_wait_ring(struct drm_device * dev, int n, const char *caller)
17 if (ring->space >= n)
18 return 0;
19
20- dev_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT;
21+ if (dev_priv->sarea_priv)
22+ dev_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT;
23
24 if (ring->head != last_head)
25 i = 0;
26@@ -128,7 +129,7 @@ void i915_kernel_lost_context(struct drm_device * dev)
27 if (ring->space < 0)
28 ring->space += ring->Size;
29
30- if (ring->head == ring->tail)
31+ if (ring->head == ring->tail && dev_priv->sarea_priv)
32 dev_priv->sarea_priv->perf_boxes |= I915_BOX_RING_EMPTY;
33 }
34
35@@ -433,10 +434,11 @@ static void i915_emit_breadcrumb(struct drm_device *dev)
36 drm_i915_private_t *dev_priv = dev->dev_private;
37 RING_LOCALS;
38
39- dev_priv->sarea_priv->last_enqueue = ++dev_priv->counter;
40-
41+ dev_priv->counter++;
42 if (dev_priv->counter > 0x7FFFFFFFUL)
43- dev_priv->sarea_priv->last_enqueue = dev_priv->counter = 1;
44+ dev_priv->counter = 0;
45+ if (dev_priv->sarea_priv)
46+ dev_priv->sarea_priv->last_enqueue = dev_priv->counter;
47
48 BEGIN_LP_RING(4);
49 OUT_RING(MI_STORE_DWORD_INDEX);
50@@ -534,6 +536,9 @@ static int i915_dispatch_flip(struct drm_device * dev)
51 drm_i915_private_t *dev_priv = dev->dev_private;
52 RING_LOCALS;
53
54+ if (!dev_priv->sarea_priv)
55+ return -EINVAL;
56+
57 DRM_DEBUG("%s: page=%d pfCurrentPage=%d\n",
58 __FUNCTION__,
59 dev_priv->current_page,
60@@ -628,7 +633,8 @@ static int i915_batchbuffer(struct drm_device *dev, void *data,
61 ret = i915_dispatch_batchbuffer(dev, batch);
62 mutex_unlock(&dev->struct_mutex);
63
64- sarea_priv->last_dispatch = (int)hw_status[5];
65+ if (sarea_priv)
66+ sarea_priv->last_dispatch = (int)hw_status[5];
67 return ret;
68 }
69
70@@ -663,7 +669,8 @@ static int i915_cmdbuffer(struct drm_device *dev, void *data,
71 return ret;
72 }
73
74- sarea_priv->last_dispatch = (int)hw_status[5];
75+ if (sarea_priv)
76+ sarea_priv->last_dispatch = (int)hw_status[5];
77 return 0;
78 }
79
80diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
81index d04c526..ef03a59 100644
82--- a/drivers/gpu/drm/i915/i915_irq.c
83+++ b/drivers/gpu/drm/i915/i915_irq.c
84@@ -427,7 +427,9 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
85 I915_WRITE(IMR, dev_priv->irq_mask_reg);
86 (void) I915_READ(IIR); /* Flush posted writes */
87
88- dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
89+ if (dev_priv->sarea_priv)
90+ dev_priv->sarea_priv->last_dispatch =
91+ READ_BREADCRUMB(dev_priv);
92
93 if (iir & I915_USER_INTERRUPT) {
94 dev_priv->mm.irq_gem_seqno = i915_get_gem_seqno(dev);
95@@ -456,10 +458,11 @@ static int i915_emit_irq(struct drm_device * dev)
96
97 DRM_DEBUG("\n");
98
99- dev_priv->sarea_priv->last_enqueue = ++dev_priv->counter;
100-
101+ dev_priv->counter++;
102 if (dev_priv->counter > 0x7FFFFFFFUL)
103- dev_priv->sarea_priv->last_enqueue = dev_priv->counter = 1;
104+ dev_priv->counter = 1;
105+ if (dev_priv->sarea_priv)
106+ dev_priv->sarea_priv->last_enqueue = dev_priv->counter;
107
108 BEGIN_LP_RING(6);
109 OUT_RING(MI_STORE_DWORD_INDEX);
110@@ -503,11 +506,15 @@ static int i915_wait_irq(struct drm_device * dev, int irq_nr)
111 READ_BREADCRUMB(dev_priv));
112
113 if (READ_BREADCRUMB(dev_priv) >= irq_nr) {
114- dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
115+ if (dev_priv->sarea_priv) {
116+ dev_priv->sarea_priv->last_dispatch =
117+ READ_BREADCRUMB(dev_priv);
118+ }
119 return 0;
120 }
121
122- dev_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT;
123+ if (dev_priv->sarea_priv)
124+ dev_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT;
125
126 i915_user_irq_get(dev);
127 DRM_WAIT_ON(ret, dev_priv->irq_queue, 3 * DRM_HZ,
128@@ -519,7 +526,9 @@ static int i915_wait_irq(struct drm_device * dev, int irq_nr)
129 READ_BREADCRUMB(dev_priv), (int)dev_priv->counter);
130 }
131
132- dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
133+ if (dev_priv->sarea_priv)
134+ dev_priv->sarea_priv->last_dispatch =
135+ READ_BREADCRUMB(dev_priv);
136
137 return ret;
138 }
139@@ -682,7 +691,7 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
140 struct list_head *list;
141 int ret;
142
143- if (!dev_priv) {
144+ if (!dev_priv || !dev_priv->sarea_priv) {
145 DRM_ERROR("%s called with no initialization\n", __func__);
146 return -EINVAL;
147 }
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27/0018-i915-gem-install-and-uninstall-irq-handler-in-enter.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27/0018-i915-gem-install-and-uninstall-irq-handler-in-enter.patch
new file mode 100644
index 0000000000..3593fa5826
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27/0018-i915-gem-install-and-uninstall-irq-handler-in-enter.patch
@@ -0,0 +1,44 @@
1commit 7ad6d5861b04bbb2cdc36d1dcf8989e16f86e659
2Author: Kristian Høgsberg <krh@redhat.com>
3Date: Wed Aug 20 11:04:27 2008 -0400
4
5 i915 gem: install and uninstall irq handler in entervt and leavevt ioctls.
6
7 Signed-off-by: Kristian Høgsberg <krh@redhat.com>
8 Signed-off-by: Eric Anholt <eric@anholt.net>
9
10diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
11index bb6e5a3..5fe5034 100644
12--- a/drivers/gpu/drm/i915/i915_gem.c
13+++ b/drivers/gpu/drm/i915/i915_gem.c
14@@ -2443,6 +2443,9 @@ i915_gem_entervt_ioctl(struct drm_device *dev, void *data,
15 BUG_ON(!list_empty(&dev_priv->mm.request_list));
16 dev_priv->mm.suspended = 0;
17 mutex_unlock(&dev->struct_mutex);
18+
19+ drm_irq_install(dev);
20+
21 return 0;
22 }
23
24@@ -2458,6 +2461,8 @@ i915_gem_leavevt_ioctl(struct drm_device *dev, void *data,
25 i915_gem_cleanup_ringbuffer(dev);
26 mutex_unlock(&dev->struct_mutex);
27
28+ drm_irq_uninstall(dev);
29+
30 return 0;
31 }
32
33diff --git a/include/drm/drmP.h b/include/drm/drmP.h
34index 1469a1b..51ee72c 100644
35--- a/include/drm/drmP.h
36+++ b/include/drm/drmP.h
37@@ -1134,6 +1134,7 @@ extern void drm_core_reclaim_buffers(struct drm_device *dev,
38 extern int drm_control(struct drm_device *dev, void *data,
39 struct drm_file *file_priv);
40 extern irqreturn_t drm_irq_handler(DRM_IRQ_ARGS);
41+extern int drm_irq_install(struct drm_device *dev);
42 extern int drm_irq_uninstall(struct drm_device *dev);
43 extern void drm_driver_irq_preinstall(struct drm_device *dev);
44 extern void drm_driver_irq_postinstall(struct drm_device *dev);
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27/0019-DRM-Return-EBADF-on-bad-object-in-flink-and-retur.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27/0019-DRM-Return-EBADF-on-bad-object-in-flink-and-retur.patch
new file mode 100644
index 0000000000..6de4514e28
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27/0019-DRM-Return-EBADF-on-bad-object-in-flink-and-retur.patch
@@ -0,0 +1,32 @@
1commit c3de45b0488762a9161e9b9e8bf419f63c100c47
2Author: Eric Anholt <eric@anholt.net>
3Date: Tue Sep 9 11:40:34 2008 -0700
4
5 DRM: Return -EBADF on bad object in flink, and return curent name if it exists.
6
7 Signed-off-by: Eric Anholt <eric@anholt.net>
8
9diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
10index 434155b..ccd1afd 100644
11--- a/drivers/gpu/drm/drm_gem.c
12+++ b/drivers/gpu/drm/drm_gem.c
13@@ -251,7 +251,7 @@ drm_gem_flink_ioctl(struct drm_device *dev, void *data,
14
15 obj = drm_gem_object_lookup(dev, file_priv, args->handle);
16 if (obj == NULL)
17- return -EINVAL;
18+ return -EBADF;
19
20 again:
21 if (idr_pre_get(&dev->object_name_idr, GFP_KERNEL) == 0)
22@@ -259,8 +259,9 @@ again:
23
24 spin_lock(&dev->object_name_lock);
25 if (obj->name) {
26+ args->name = obj->name;
27 spin_unlock(&dev->object_name_lock);
28- return -EEXIST;
29+ return 0;
30 }
31 ret = idr_get_new_above(&dev->object_name_idr, obj, 1,
32 &obj->name);
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27/0020-drm-Avoid-oops-in-GEM-execbuffers-with-bad-argument.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27/0020-drm-Avoid-oops-in-GEM-execbuffers-with-bad-argument.patch
new file mode 100644
index 0000000000..7080907cde
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27/0020-drm-Avoid-oops-in-GEM-execbuffers-with-bad-argument.patch
@@ -0,0 +1,23 @@
1commit 880db7a8dbed226d638b3a48aa1a3996f8624911
2Author: Eric Anholt <eric@anholt.net>
3Date: Wed Sep 10 14:22:49 2008 -0700
4
5 drm: Avoid oops in GEM execbuffers with bad arguments.
6
7 Signed-off-by: Eric Anholt <eric@anholt.net>
8
9diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
10index 5fe5034..29d9d21 100644
11--- a/drivers/gpu/drm/i915/i915_gem.c
12+++ b/drivers/gpu/drm/i915/i915_gem.c
13@@ -1763,6 +1763,10 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
14 (int) args->buffers_ptr, args->buffer_count, args->batch_len);
15 #endif
16
17+ if (args->buffer_count < 1) {
18+ DRM_ERROR("execbuf with %d buffers\n", args->buffer_count);
19+ return -EINVAL;
20+ }
21 /* Copy in the exec list from userland */
22 exec_list = drm_calloc(sizeof(*exec_list), args->buffer_count,
23 DRM_MEM_DRIVER);
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27/0021-drm-G33-class-hardware-has-a-newer-965-style-MCH-n.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27/0021-drm-G33-class-hardware-has-a-newer-965-style-MCH-n.patch
new file mode 100644
index 0000000000..f5481d7d85
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27/0021-drm-G33-class-hardware-has-a-newer-965-style-MCH-n.patch
@@ -0,0 +1,23 @@
1commit 930469634910fa87c21f0a7423c98b270d35d8c6
2Author: Eric Anholt <eric@anholt.net>
3Date: Mon Sep 15 13:13:34 2008 -0700
4
5 drm: G33-class hardware has a newer 965-style MCH (no DCC register).
6
7 Fixes bad software fallback rendering in Mesa in dual-channel configurations.
8
9 d9a2470012588dc5313a5ac8bb2f03575af00e99
10
11diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c
12index 0c1b3a0..6b3f1e4 100644
13--- a/drivers/gpu/drm/i915/i915_gem_tiling.c
14+++ b/drivers/gpu/drm/i915/i915_gem_tiling.c
15@@ -96,7 +96,7 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev)
16 */
17 swizzle_x = I915_BIT_6_SWIZZLE_NONE;
18 swizzle_y = I915_BIT_6_SWIZZLE_NONE;
19- } else if (!IS_I965G(dev) || IS_I965GM(dev)) {
20+ } else if ((!IS_I965G(dev) && !IS_G33(dev)) || IS_I965GM(dev)) {
21 uint32_t dcc;
22
23 /* On 915-945 and GM965, channel interleave by the CPU is
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27/0022-drm-use-ioremap_wc-in-i915-instead-of-ioremap.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27/0022-drm-use-ioremap_wc-in-i915-instead-of-ioremap.patch
new file mode 100644
index 0000000000..8e6cbe95a4
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27/0022-drm-use-ioremap_wc-in-i915-instead-of-ioremap.patch
@@ -0,0 +1,58 @@
1commit d9f2382adde582f8792ad96e9570716bcbea21a0
2Author: Eric Anholt <eric@anholt.net>
3Date: Tue Sep 23 14:50:57 2008 -0700
4
5 drm: Use ioremap_wc in i915_driver instead of ioremap, since we always want WC.
6
7 Fixes failure to map the ringbuffer when PAT tells us we don't get to do
8 uncached on something that's already mapped WC, or something along those lines.
9
10 Signed-off-by: Eric Anholt <eric@anholt.net>
11
12diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
13index 29d9d21..6ecfd10 100644
14--- a/drivers/gpu/drm/i915/i915_gem.c
15+++ b/drivers/gpu/drm/i915/i915_gem.c
16@@ -233,7 +233,7 @@ i915_gem_gtt_pwrite(struct drm_device *dev, struct drm_gem_object *obj,
17 if (unwritten)
18 #endif /* CONFIG_HIGHMEM */
19 {
20- vaddr = ioremap(pfn << PAGE_SHIFT, PAGE_SIZE);
21+ vaddr = ioremap_wc(pfn << PAGE_SHIFT, PAGE_SIZE);
22 #if WATCH_PWRITE
23 DRM_INFO("pwrite slow i %d o %d l %d "
24 "pfn %ld vaddr %p\n",
25@@ -1612,9 +1612,10 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj,
26 if (reloc_page != NULL)
27 iounmap(reloc_page);
28
29- reloc_page = ioremap(dev->agp->base +
30- (reloc_offset & ~(PAGE_SIZE - 1)),
31- PAGE_SIZE);
32+ reloc_page = ioremap_wc(dev->agp->base +
33+ (reloc_offset &
34+ ~(PAGE_SIZE - 1)),
35+ PAGE_SIZE);
36 last_reloc_offset = reloc_offset;
37 if (reloc_page == NULL) {
38 drm_gem_object_unreference(target_obj);
39@@ -2318,7 +2319,9 @@ i915_gem_init_hws(struct drm_device *dev)
40 dev_priv->hws_map.flags = 0;
41 dev_priv->hws_map.mtrr = 0;
42
43- drm_core_ioremap(&dev_priv->hws_map, dev);
44+ /* Ioremapping here is the wrong thing to do. We want cached access.
45+ */
46+ drm_core_ioremap_wc(&dev_priv->hws_map, dev);
47 if (dev_priv->hws_map.handle == NULL) {
48 DRM_ERROR("Failed to map status page.\n");
49 memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map));
50@@ -2369,7 +2372,7 @@ i915_gem_init_ringbuffer(struct drm_device *dev)
51 dev_priv->ring.map.flags = 0;
52 dev_priv->ring.map.mtrr = 0;
53
54- drm_core_ioremap(&dev_priv->ring.map, dev);
55+ drm_core_ioremap_wc(&dev_priv->ring.map, dev);
56 if (dev_priv->ring.map.handle == NULL) {
57 DRM_ERROR("Failed to map ringbuffer.\n");
58 memset(&dev_priv->ring, 0, sizeof(dev_priv->ring));
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27/0023-drm-clean-up-many-sparse-warnings-in-i915.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27/0023-drm-clean-up-many-sparse-warnings-in-i915.patch
new file mode 100644
index 0000000000..236b161587
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27/0023-drm-clean-up-many-sparse-warnings-in-i915.patch
@@ -0,0 +1,192 @@
1commit 034994cfffbb2371b720e3f49378031ebc12645e
2Author: Eric Anholt <eric@anholt.net>
3Date: Thu Oct 2 12:24:47 2008 -0700
4
5 drm: Clean up many sparse warnings in i915.
6
7 Signed-off-by: Eric Anholt <eric@anholt.net>
8
9diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
10index dbd3f49..814cc12 100644
11--- a/drivers/gpu/drm/i915/i915_dma.c
12+++ b/drivers/gpu/drm/i915/i915_dma.c
13@@ -76,7 +76,7 @@ int i915_wait_ring(struct drm_device * dev, int n, const char *caller)
14 * Sets up the hardware status page for devices that need a physical address
15 * in the register.
16 */
17-int i915_init_phys_hws(struct drm_device *dev)
18+static int i915_init_phys_hws(struct drm_device *dev)
19 {
20 drm_i915_private_t *dev_priv = dev->dev_private;
21 /* Program Hardware Status Page */
22@@ -101,7 +101,7 @@ int i915_init_phys_hws(struct drm_device *dev)
23 * Frees the hardware status page, whether it's a physical address or a virtual
24 * address set up by the X Server.
25 */
26-void i915_free_hws(struct drm_device *dev)
27+static void i915_free_hws(struct drm_device *dev)
28 {
29 drm_i915_private_t *dev_priv = dev->dev_private;
30 if (dev_priv->status_page_dmah) {
31@@ -145,8 +145,8 @@ static int i915_dma_cleanup(struct drm_device * dev)
32
33 if (dev_priv->ring.virtual_start) {
34 drm_core_ioremapfree(&dev_priv->ring.map, dev);
35- dev_priv->ring.virtual_start = 0;
36- dev_priv->ring.map.handle = 0;
37+ dev_priv->ring.virtual_start = NULL;
38+ dev_priv->ring.map.handle = NULL;
39 dev_priv->ring.map.size = 0;
40 }
41
42@@ -827,9 +827,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
43 base = drm_get_resource_start(dev, mmio_bar);
44 size = drm_get_resource_len(dev, mmio_bar);
45
46- ret = drm_addmap(dev, base, size, _DRM_REGISTERS,
47- _DRM_KERNEL | _DRM_DRIVER,
48- &dev_priv->mmio_map);
49+ dev_priv->regs = ioremap(base, size);
50
51 i915_gem_load(dev);
52
53@@ -867,8 +865,8 @@ int i915_driver_unload(struct drm_device *dev)
54
55 i915_free_hws(dev);
56
57- if (dev_priv->mmio_map)
58- drm_rmmap(dev, dev_priv->mmio_map);
59+ if (dev_priv->regs != NULL)
60+ iounmap(dev_priv->regs);
61
62 intel_opregion_free(dev);
63
64diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
65index 8547f0a..b184d54 100644
66--- a/drivers/gpu/drm/i915/i915_drv.h
67+++ b/drivers/gpu/drm/i915/i915_drv.h
68@@ -110,8 +110,8 @@ struct intel_opregion {
69 typedef struct drm_i915_private {
70 struct drm_device *dev;
71
72+ void __iomem *regs;
73 drm_local_map_t *sarea;
74- drm_local_map_t *mmio_map;
75
76 drm_i915_sarea_t *sarea_priv;
77 drm_i915_ring_buffer_t ring;
78@@ -553,12 +553,12 @@ extern void opregion_enable_asle(struct drm_device *dev);
79 LOCK_TEST_WITH_RETURN(dev, file_priv); \
80 } while (0)
81
82-#define I915_READ(reg) DRM_READ32(dev_priv->mmio_map, (reg))
83-#define I915_WRITE(reg,val) DRM_WRITE32(dev_priv->mmio_map, (reg), (val))
84-#define I915_READ16(reg) DRM_READ16(dev_priv->mmio_map, (reg))
85-#define I915_WRITE16(reg,val) DRM_WRITE16(dev_priv->mmio_map, (reg), (val))
86-#define I915_READ8(reg) DRM_READ8(dev_priv->mmio_map, (reg))
87-#define I915_WRITE8(reg,val) DRM_WRITE8(dev_priv->mmio_map, (reg), (val))
88+#define I915_READ(reg) readl(dev_priv->regs + (reg))
89+#define I915_WRITE(reg,val) writel(val, dev_priv->regs + (reg))
90+#define I915_READ16(reg) readw(dev_priv->regs + (reg))
91+#define I915_WRITE16(reg,val) writel(val, dev_priv->regs + (reg))
92+#define I915_READ8(reg) readb(dev_priv->regs + (reg))
93+#define I915_WRITE8(reg,val) writeb(val, dev_priv->regs + (reg))
94
95 #define I915_VERBOSE 0
96
97diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
98index 6ecfd10..6a89449 100644
99--- a/drivers/gpu/drm/i915/i915_gem.c
100+++ b/drivers/gpu/drm/i915/i915_gem.c
101@@ -176,7 +176,8 @@ i915_gem_gtt_pwrite(struct drm_device *dev, struct drm_gem_object *obj,
102 ssize_t remain;
103 loff_t offset;
104 char __user *user_data;
105- char *vaddr;
106+ char __iomem *vaddr;
107+ char *vaddr_atomic;
108 int i, o, l;
109 int ret = 0;
110 unsigned long pfn;
111@@ -219,16 +220,20 @@ i915_gem_gtt_pwrite(struct drm_device *dev, struct drm_gem_object *obj,
112 pfn = (dev->agp->base >> PAGE_SHIFT) + i;
113
114 #ifdef CONFIG_HIGHMEM
115- /* kmap_atomic can't map IO pages on non-HIGHMEM kernels
116+ /* This is a workaround for the low performance of iounmap
117+ * (approximate 10% cpu cost on normal 3D workloads).
118+ * kmap_atomic on HIGHMEM kernels happens to let us map card
119+ * memory without taking IPIs. When the vmap rework lands
120+ * we should be able to dump this hack.
121 */
122- vaddr = kmap_atomic_pfn(pfn, KM_USER0);
123+ vaddr_atomic = kmap_atomic_pfn(pfn, KM_USER0);
124 #if WATCH_PWRITE
125 DRM_INFO("pwrite i %d o %d l %d pfn %ld vaddr %p\n",
126- i, o, l, pfn, vaddr);
127+ i, o, l, pfn, vaddr_atomic);
128 #endif
129- unwritten = __copy_from_user_inatomic_nocache(vaddr + o,
130+ unwritten = __copy_from_user_inatomic_nocache(vaddr_atomic + o,
131 user_data, l);
132- kunmap_atomic(vaddr, KM_USER0);
133+ kunmap_atomic(vaddr_atomic, KM_USER0);
134
135 if (unwritten)
136 #endif /* CONFIG_HIGHMEM */
137@@ -271,7 +276,7 @@ fail:
138 return ret;
139 }
140
141-int
142+static int
143 i915_gem_shmem_pwrite(struct drm_device *dev, struct drm_gem_object *obj,
144 struct drm_i915_gem_pwrite *args,
145 struct drm_file *file_priv)
146@@ -587,7 +592,7 @@ i915_add_request(struct drm_device *dev, uint32_t flush_domains)
147 * Ensures that all commands in the ring are finished
148 * before signalling the CPU
149 */
150-uint32_t
151+static uint32_t
152 i915_retire_commands(struct drm_device *dev)
153 {
154 drm_i915_private_t *dev_priv = dev->dev_private;
155@@ -734,7 +739,7 @@ i915_gem_retire_work_handler(struct work_struct *work)
156 * Waits for a sequence number to be signaled, and cleans up the
157 * request and object lists appropriately for that event.
158 */
159-int
160+static int
161 i915_wait_request(struct drm_device *dev, uint32_t seqno)
162 {
163 drm_i915_private_t *dev_priv = dev->dev_private;
164@@ -1483,7 +1488,7 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj,
165 struct drm_i915_gem_object *obj_priv = obj->driver_private;
166 int i, ret;
167 uint32_t last_reloc_offset = -1;
168- void *reloc_page = NULL;
169+ void __iomem *reloc_page = NULL;
170
171 /* Choose the GTT offset for our buffer and put it there. */
172 ret = i915_gem_object_pin(obj, (uint32_t) entry->alignment);
173@@ -1500,8 +1505,8 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj,
174 for (i = 0; i < entry->relocation_count; i++) {
175 struct drm_gem_object *target_obj;
176 struct drm_i915_gem_object *target_obj_priv;
177- uint32_t reloc_val, reloc_offset, *reloc_entry;
178- int ret;
179+ uint32_t reloc_val, reloc_offset;
180+ uint32_t __iomem *reloc_entry;
181
182 ret = copy_from_user(&reloc, relocs + i, sizeof(reloc));
183 if (ret != 0) {
184@@ -1624,7 +1629,7 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj,
185 }
186 }
187
188- reloc_entry = (uint32_t *)((char *)reloc_page +
189+ reloc_entry = (uint32_t __iomem *)(reloc_page +
190 (reloc_offset & (PAGE_SIZE - 1)));
191 reloc_val = target_obj_priv->gtt_offset + reloc.delta;
192
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27/0024-fastboot-create-a-asynchronous-initlevel.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27/0024-fastboot-create-a-asynchronous-initlevel.patch
new file mode 100644
index 0000000000..db518b36eb
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27/0024-fastboot-create-a-asynchronous-initlevel.patch
@@ -0,0 +1,133 @@
1From ac9103dd8e4dc65c110d6cba9a3380c6c617ffa7 Mon Sep 17 00:00:00 2001
2From: Arjan van de Ven <arjan@linux.intel.com>
3Date: Fri, 18 Jul 2008 15:16:08 -0700
4Subject: [PATCH] fastboot: create a "asynchronous" initlevel
5
6This patch creates an asynchronous initlevel (6a) which is at the same
7level as the normal device initcalls, but with the difference that they
8are run asynchronous from all the other initcalls. The purpose of this
9*selective* level is that we can move long waiting inits that are not
10boot-critical to this level one at a time.
11
12To keep things not totally insane, the asynchronous initcalls are async
13to the other initcalls, but are still ordered to themselves; think of it
14as "bottom-half-not-softirq". This has the benefit that async drivers
15still have stable device ordering between them.
16
17Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
18Signed-off-by: Ingo Molnar <mingo@elte.hu>
19---
20 include/asm-generic/vmlinux.lds.h | 3 +++
21 include/linux/init.h | 6 ++++++
22 init/main.c | 35 ++++++++++++++++++++++++++++++++---
23 3 files changed, 41 insertions(+), 3 deletions(-)
24
25Index: linux-2.6.27/include/asm-generic/vmlinux.lds.h
26===================================================================
27--- linux-2.6.27.orig/include/asm-generic/vmlinux.lds.h 2008-10-14 16:55:43.000000000 +0200
28+++ linux-2.6.27/include/asm-generic/vmlinux.lds.h 2008-10-14 17:00:59.000000000 +0200
29@@ -376,6 +376,9 @@
30 *(.initcall5.init) \
31 *(.initcall5s.init) \
32 *(.initcallrootfs.init) \
33+ __async_initcall_start = .; \
34+ *(.initcall6a.init) \
35+ __async_initcall_end = .; \
36 *(.initcall6.init) \
37 *(.initcall6s.init) \
38 *(.initcall7.init) \
39Index: linux-2.6.27/include/linux/init.h
40===================================================================
41--- linux-2.6.27.orig/include/linux/init.h 2008-10-14 16:55:45.000000000 +0200
42+++ linux-2.6.27/include/linux/init.h 2008-10-14 17:00:59.000000000 +0200
43@@ -197,11 +197,13 @@ extern void (*late_time_init)(void);
44 #define fs_initcall_sync(fn) __define_initcall("5s",fn,5s)
45 #define rootfs_initcall(fn) __define_initcall("rootfs",fn,rootfs)
46 #define device_initcall(fn) __define_initcall("6",fn,6)
47+#define device_initcall_async(fn) __define_initcall("6a", fn, 6a)
48 #define device_initcall_sync(fn) __define_initcall("6s",fn,6s)
49 #define late_initcall(fn) __define_initcall("7",fn,7)
50 #define late_initcall_sync(fn) __define_initcall("7s",fn,7s)
51
52 #define __initcall(fn) device_initcall(fn)
53+#define __initcall_async(fn) device_initcall_async(fn)
54
55 #define __exitcall(fn) \
56 static exitcall_t __exitcall_##fn __exit_call = fn
57@@ -257,6 +259,7 @@ void __init parse_early_param(void);
58 * be one per module.
59 */
60 #define module_init(x) __initcall(x);
61+#define module_init_async(x) __initcall_async(x);
62
63 /**
64 * module_exit() - driver exit entry point
65@@ -279,10 +282,13 @@ void __init parse_early_param(void);
66 #define subsys_initcall(fn) module_init(fn)
67 #define fs_initcall(fn) module_init(fn)
68 #define device_initcall(fn) module_init(fn)
69+#define device_initcall_async(fn) module_init(fn)
70 #define late_initcall(fn) module_init(fn)
71
72 #define security_initcall(fn) module_init(fn)
73
74+#define module_init_async(fn) module_init(fn)
75+
76 /* Each module must use one module_init(). */
77 #define module_init(initfn) \
78 static inline initcall_t __inittest(void) \
79Index: linux-2.6.27/init/main.c
80===================================================================
81--- linux-2.6.27.orig/init/main.c 2008-10-14 16:55:47.000000000 +0200
82+++ linux-2.6.27/init/main.c 2008-10-14 17:00:59.000000000 +0200
83@@ -745,18 +745,47 @@ int do_one_initcall(initcall_t fn)
84
85
86 extern initcall_t __initcall_start[], __initcall_end[], __early_initcall_end[];
87+extern initcall_t __async_initcall_start[], __async_initcall_end[];
88
89-static void __init do_initcalls(void)
90+static void __init do_async_initcalls(struct work_struct *dummy)
91 {
92 initcall_t *call;
93
94- for (call = __early_initcall_end; call < __initcall_end; call++)
95+ for (call = __async_initcall_start; call < __async_initcall_end; call++)
96 do_one_initcall(*call);
97+}
98+
99+static struct workqueue_struct *async_init_wq;
100+
101+static void __init do_initcalls(void)
102+{
103+ initcall_t *call;
104+ static DECLARE_WORK(async_work, do_async_initcalls);
105+ int phase = 0; /* 0 = levels 0 - 6, 1 = level 6a, 2 = after level 6a */
106+
107+ async_init_wq = create_singlethread_workqueue("kasyncinit");
108+
109+ for (call = __early_initcall_end; call < __initcall_end; call++) {
110+ if (phase == 0 && call >= __async_initcall_start) {
111+ phase = 1;
112+ queue_work(async_init_wq, &async_work);
113+ }
114+ if (phase == 1 && call >= __async_initcall_end)
115+ phase = 2;
116+ if (phase != 1)
117+ do_one_initcall(*call);
118+ }
119
120- /* Make sure there is no pending stuff from the initcall sequence */
121+ /*
122+ * Make sure there is no pending stuff from the initcall sequence,
123+ * including the async initcalls
124+ */
125 flush_scheduled_work();
126+ flush_workqueue(async_init_wq);
127+ destroy_workqueue(async_init_wq);
128 }
129
130+
131 /*
132 * Ok, the machine is now initialized. None of the devices
133 * have been touched yet, but the CPU subsystem is up and
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27/0025-fastboot-turn-the-USB-hostcontroller-initcalls-into.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27/0025-fastboot-turn-the-USB-hostcontroller-initcalls-into.patch
new file mode 100644
index 0000000000..f6db800c71
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27/0025-fastboot-turn-the-USB-hostcontroller-initcalls-into.patch
@@ -0,0 +1,59 @@
1From d1a26186ee222329a797bb0b2c8e2b5bc7d94d42 Mon Sep 17 00:00:00 2001
2From: Arjan van de Ven <arjan@linux.intel.com>
3Date: Fri, 18 Jul 2008 15:16:53 -0700
4Subject: [PATCH] fastboot: turn the USB hostcontroller initcalls into async initcalls
5
6the USB host controller init calls take a long time, mostly due to a
7"minimally 100 msec" delay *per port* during initialization.
8These are prime candidates for going in parallel to everything else.
9
10The USB device ordering is not affected by this due to the
11serialized-within-eachother property of async initcalls.
12
13Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
14Signed-off-by: Ingo Molnar <mingo@elte.hu>
15---
16 drivers/usb/host/ehci-hcd.c | 2 +-
17 drivers/usb/host/ohci-hcd.c | 2 +-
18 drivers/usb/host/uhci-hcd.c | 2 +-
19 3 files changed, 3 insertions(+), 3 deletions(-)
20
21Index: linux-2.6.27/drivers/usb/host/ehci-hcd.c
22===================================================================
23--- linux-2.6.27.orig/drivers/usb/host/ehci-hcd.c 2008-10-14 16:55:35.000000000 +0200
24+++ linux-2.6.27/drivers/usb/host/ehci-hcd.c 2008-10-14 17:01:27.000000000 +0200
25@@ -1107,7 +1107,7 @@ clean0:
26 #endif
27 return retval;
28 }
29-module_init(ehci_hcd_init);
30+module_init_async(ehci_hcd_init);
31
32 static void __exit ehci_hcd_cleanup(void)
33 {
34Index: linux-2.6.27/drivers/usb/host/ohci-hcd.c
35===================================================================
36--- linux-2.6.27.orig/drivers/usb/host/ohci-hcd.c 2008-10-14 16:55:35.000000000 +0200
37+++ linux-2.6.27/drivers/usb/host/ohci-hcd.c 2008-10-14 17:01:27.000000000 +0200
38@@ -1186,7 +1186,7 @@ static int __init ohci_hcd_mod_init(void
39
40 return retval;
41 }
42-module_init(ohci_hcd_mod_init);
43+module_init_async(ohci_hcd_mod_init);
44
45 static void __exit ohci_hcd_mod_exit(void)
46 {
47Index: linux-2.6.27/drivers/usb/host/uhci-hcd.c
48===================================================================
49--- linux-2.6.27.orig/drivers/usb/host/uhci-hcd.c 2008-10-14 16:55:35.000000000 +0200
50+++ linux-2.6.27/drivers/usb/host/uhci-hcd.c 2008-10-14 17:01:27.000000000 +0200
51@@ -999,7 +999,7 @@ static void __exit uhci_hcd_cleanup(void
52 kfree(errbuf);
53 }
54
55-module_init(uhci_hcd_init);
56+module_init_async(uhci_hcd_init);
57 module_exit(uhci_hcd_cleanup);
58
59 MODULE_AUTHOR(DRIVER_AUTHOR);
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27/0026-fastboot-convert-a-few-non-critical-ACPI-drivers-to.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27/0026-fastboot-convert-a-few-non-critical-ACPI-drivers-to.patch
new file mode 100644
index 0000000000..4b10a93108
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27/0026-fastboot-convert-a-few-non-critical-ACPI-drivers-to.patch
@@ -0,0 +1,51 @@
1From 60ddc2e5c44b4b9f5fcb440065469eacbeabf5eb Mon Sep 17 00:00:00 2001
2From: Arjan van de Ven <arjan@linux.intel.com>
3Date: Fri, 18 Jul 2008 15:17:35 -0700
4Subject: [PATCH] fastboot: convert a few non-critical ACPI drivers to async initcalls
5
6This patch converts a few non-critical ACPI drivers to async initcalls;
7these initcalls (battery, button and thermal) tend to take quite a bit of
8time (100's of milliseconds) due to the hardware they need to talk to,
9but are otherwise clearly non-essential for the boot process.
10
11Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
12Signed-off-by: Ingo Molnar <mingo@elte.hu>
13---
14 drivers/acpi/battery.c | 2 +-
15 drivers/acpi/button.c | 2 +-
16 drivers/acpi/thermal.c | 2 +-
17 3 files changed, 3 insertions(+), 3 deletions(-)
18
19Index: linux-2.6.27/drivers/acpi/battery.c
20===================================================================
21--- linux-2.6.27.orig/drivers/acpi/battery.c 2008-10-14 16:55:15.000000000 +0200
22+++ linux-2.6.27/drivers/acpi/battery.c 2008-10-14 17:01:33.000000000 +0200
23@@ -904,5 +904,5 @@ static void __exit acpi_battery_exit(voi
24 #endif
25 }
26
27-module_init(acpi_battery_init);
28+module_init_async(acpi_battery_init);
29 module_exit(acpi_battery_exit);
30Index: linux-2.6.27/drivers/acpi/button.c
31===================================================================
32--- linux-2.6.27.orig/drivers/acpi/button.c 2008-10-14 16:55:15.000000000 +0200
33+++ linux-2.6.27/drivers/acpi/button.c 2008-10-14 17:01:33.000000000 +0200
34@@ -545,5 +545,5 @@ static void __exit acpi_button_exit(void
35 remove_proc_entry(ACPI_BUTTON_CLASS, acpi_root_dir);
36 }
37
38-module_init(acpi_button_init);
39+module_init_async(acpi_button_init);
40 module_exit(acpi_button_exit);
41Index: linux-2.6.27/drivers/acpi/thermal.c
42===================================================================
43--- linux-2.6.27.orig/drivers/acpi/thermal.c 2008-10-14 16:55:15.000000000 +0200
44+++ linux-2.6.27/drivers/acpi/thermal.c 2008-10-14 17:01:33.000000000 +0200
45@@ -1876,5 +1876,5 @@ static void __exit acpi_thermal_exit(voi
46 return;
47 }
48
49-module_init(acpi_thermal_init);
50+module_init_async(acpi_thermal_init);
51 module_exit(acpi_thermal_exit);
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27/0027-fastboot-hold-the-BKL-over-the-async-init-call-sequ.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27/0027-fastboot-hold-the-BKL-over-the-async-init-call-sequ.patch
new file mode 100644
index 0000000000..11fb34dd91
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27/0027-fastboot-hold-the-BKL-over-the-async-init-call-sequ.patch
@@ -0,0 +1,37 @@
1From 3e6558b693dd1e69e3177bc248977f067a769f14 Mon Sep 17 00:00:00 2001
2From: Arjan van de Ven <arjan@linux.intel.com>
3Date: Sun, 20 Jul 2008 08:59:24 -0700
4Subject: [PATCH] fastboot: hold the BKL over the async init call sequence
5
6Regular init calls are called with the BKL held; make sure
7the async init calls are also called with the BKL held.
8While this reduces parallelism a little, it does provide
9lock-for-lock compatibility. The hit to prallelism isn't too
10bad, most of the init calls are done immediately or actually
11block for their delays.
12
13Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
14Signed-off-by: Ingo Molnar <mingo@elte.hu>
15---
16 init/main.c | 6 ++++++
17 1 file changed, 6 insertions(+)
18
19Index: linux-2.6.27/init/main.c
20===================================================================
21--- linux-2.6.27.orig/init/main.c 2008-10-14 17:00:59.000000000 +0200
22+++ linux-2.6.27/init/main.c 2008-10-14 17:01:38.000000000 +0200
23@@ -751,8 +751,14 @@ static void __init do_async_initcalls(st
24 {
25 initcall_t *call;
26
27+ /*
28+ * For compatibility with normal init calls... take the BKL
29+ * not pretty, not desirable, but compatibility first
30+ */
31+ lock_kernel();
32 for (call = __async_initcall_start; call < __async_initcall_end; call++)
33 do_one_initcall(*call);
34+ unlock_kernel();
35 }
36
37 static struct workqueue_struct *async_init_wq;
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27/0028-fastboot-sync-the-async-execution-before-late_initc.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27/0028-fastboot-sync-the-async-execution-before-late_initc.patch
new file mode 100644
index 0000000000..d1ff95a39f
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27/0028-fastboot-sync-the-async-execution-before-late_initc.patch
@@ -0,0 +1,92 @@
1From 660625fb93f2fc0e633da9cb71d13d895b385f64 Mon Sep 17 00:00:00 2001
2From: Arjan van de Ven <arjan@linux.intel.com>
3Date: Sun, 20 Jul 2008 09:00:41 -0700
4Subject: [PATCH] fastboot: sync the async execution before late_initcall and move level 6s (sync) first
5
6Rene Herman points out several cases where it's basically needed to have
7all level 6/6a/6s calls done before the level 7 (late_initcall) code
8runs. This patch adds a sync point in the transition from the 6's to the
97's.
10
11Second, this patch makes sure that level 6s (sync) happens before the
12async code starts, and puts a user in driver/pci in this category that
13needs to happen before device init.
14
15Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
16Signed-off-by: Ingo Molnar <mingo@elte.hu>
17---
18 drivers/pci/pci.c | 2 +-
19 include/asm-generic/vmlinux.lds.h | 3 ++-
20 init/main.c | 14 +++++++++++++-
21 3 files changed, 16 insertions(+), 3 deletions(-)
22
23Index: linux-2.6.27/drivers/pci/pci.c
24===================================================================
25--- linux-2.6.27.orig/drivers/pci/pci.c 2008-10-14 16:55:30.000000000 +0200
26+++ linux-2.6.27/drivers/pci/pci.c 2008-10-14 17:01:42.000000000 +0200
27@@ -1909,7 +1909,7 @@ static int __devinit pci_setup(char *str
28 }
29 early_param("pci", pci_setup);
30
31-device_initcall(pci_init);
32+device_initcall_sync(pci_init);
33
34 EXPORT_SYMBOL(pci_reenable_device);
35 EXPORT_SYMBOL(pci_enable_device_io);
36Index: linux-2.6.27/include/asm-generic/vmlinux.lds.h
37===================================================================
38--- linux-2.6.27.orig/include/asm-generic/vmlinux.lds.h 2008-10-14 17:00:59.000000000 +0200
39+++ linux-2.6.27/include/asm-generic/vmlinux.lds.h 2008-10-14 17:01:42.000000000 +0200
40@@ -376,11 +376,12 @@
41 *(.initcall5.init) \
42 *(.initcall5s.init) \
43 *(.initcallrootfs.init) \
44+ *(.initcall6s.init) \
45 __async_initcall_start = .; \
46 *(.initcall6a.init) \
47 __async_initcall_end = .; \
48 *(.initcall6.init) \
49- *(.initcall6s.init) \
50+ __device_initcall_end = .; \
51 *(.initcall7.init) \
52 *(.initcall7s.init)
53
54Index: linux-2.6.27/init/main.c
55===================================================================
56--- linux-2.6.27.orig/init/main.c 2008-10-14 17:01:38.000000000 +0200
57+++ linux-2.6.27/init/main.c 2008-10-14 17:01:42.000000000 +0200
58@@ -746,6 +746,7 @@ int do_one_initcall(initcall_t fn)
59
60 extern initcall_t __initcall_start[], __initcall_end[], __early_initcall_end[];
61 extern initcall_t __async_initcall_start[], __async_initcall_end[];
62+extern initcall_t __device_initcall_end[];
63
64 static void __init do_async_initcalls(struct work_struct *dummy)
65 {
66@@ -767,7 +768,13 @@ static void __init do_initcalls(void)
67 {
68 initcall_t *call;
69 static DECLARE_WORK(async_work, do_async_initcalls);
70- int phase = 0; /* 0 = levels 0 - 6, 1 = level 6a, 2 = after level 6a */
71+ /*
72+ * 0 = levels 0 - 6,
73+ * 1 = level 6a,
74+ * 2 = after level 6a,
75+ * 3 = after level 6
76+ */
77+ int phase = 0;
78
79 async_init_wq = create_singlethread_workqueue("kasyncinit");
80
81@@ -778,6 +785,11 @@ static void __init do_initcalls(void)
82 }
83 if (phase == 1 && call >= __async_initcall_end)
84 phase = 2;
85+ if (phase == 2 && call >= __device_initcall_end) {
86+ phase = 3;
87+ /* make sure all async work is done before level 7 */
88+ flush_workqueue(async_init_wq);
89+ }
90 if (phase != 1)
91 do_one_initcall(*call);
92 }
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27/0029-fastboot-make-fastboot-a-config-option.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27/0029-fastboot-make-fastboot-a-config-option.patch
new file mode 100644
index 0000000000..73b856372f
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27/0029-fastboot-make-fastboot-a-config-option.patch
@@ -0,0 +1,53 @@
1From 50b6962016b824dfac254b8f36fc6cac301c8a8d Mon Sep 17 00:00:00 2001
2From: Arjan van de Ven <arjan@linux.intel.com>
3Date: Sun, 20 Jul 2008 10:20:49 -0700
4Subject: [PATCH] fastboot: make fastboot a config option
5
6to mitigate the risks of async bootup, make fastboot a configuration
7option...
8
9Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
10Signed-off-by: Ingo Molnar <mingo@elte.hu>
11---
12 init/Kconfig | 11 +++++++++++
13 init/main.c | 4 ++++
14 2 files changed, 15 insertions(+)
15
16Index: linux-2.6.27/init/Kconfig
17===================================================================
18--- linux-2.6.27.orig/init/Kconfig 2008-10-14 16:55:47.000000000 +0200
19+++ linux-2.6.27/init/Kconfig 2008-10-14 17:01:48.000000000 +0200
20@@ -524,6 +524,17 @@ config CC_OPTIMIZE_FOR_SIZE
21
22 If unsure, say Y.
23
24+config FASTBOOT
25+ bool "Fast boot support"
26+ help
27+ The fastboot option will cause the kernel to try to optimize
28+ for faster boot.
29+
30+ This includes doing some of the device initialization asynchronous
31+ as well as opportunistically trying to mount the root fs early.
32+
33+ If unsure, say N.
34+
35 config SYSCTL
36 bool
37
38Index: linux-2.6.27/init/main.c
39===================================================================
40--- linux-2.6.27.orig/init/main.c 2008-10-14 17:01:42.000000000 +0200
41+++ linux-2.6.27/init/main.c 2008-10-14 17:01:48.000000000 +0200
42@@ -781,7 +781,11 @@ static void __init do_initcalls(void)
43 for (call = __early_initcall_end; call < __initcall_end; call++) {
44 if (phase == 0 && call >= __async_initcall_start) {
45 phase = 1;
46+#ifdef CONFIG_FASTBOOT
47 queue_work(async_init_wq, &async_work);
48+#else
49+ do_async_initcalls(NULL);
50+#endif
51 }
52 if (phase == 1 && call >= __async_initcall_end)
53 phase = 2;
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27/0030-fastboot-retry-mounting-the-root-fs-if-we-can-t-fin.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27/0030-fastboot-retry-mounting-the-root-fs-if-we-can-t-fin.patch
new file mode 100644
index 0000000000..0e0c7fa84f
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27/0030-fastboot-retry-mounting-the-root-fs-if-we-can-t-fin.patch
@@ -0,0 +1,64 @@
1From db62cd29f9b9142c19c574ca00916f66ff22ed4a Mon Sep 17 00:00:00 2001
2From: Arjan van de Ven <arjan@linux.intel.com>
3Date: Sun, 20 Jul 2008 13:01:28 -0700
4Subject: [PATCH] fastboot: retry mounting the root fs if we can't find init
5
6currently we wait until all device init is done before trying to mount
7the root fs, and to consequently execute init.
8
9In preparation for relaxing the first delay, this patch adds a retry
10attempt in case /sbin/init is not found. Before retrying, the code
11will wait for all device init to complete.
12
13While this patch by itself doesn't gain boot time yet (it needs follow on
14patches), the alternative already is to panic()...
15
16Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
17---
18 init/main.c | 19 +++++++++++++++++++
19 1 file changed, 19 insertions(+)
20
21Index: linux-2.6.27/init/main.c
22===================================================================
23--- linux-2.6.27.orig/init/main.c 2008-10-14 17:01:48.000000000 +0200
24+++ linux-2.6.27/init/main.c 2008-10-14 17:02:42.000000000 +0200
25@@ -845,6 +845,7 @@ static void run_init_process(char *init_
26 */
27 static int noinline init_post(void)
28 {
29+ int retry_count = 1;
30 free_initmem();
31 unlock_kernel();
32 mark_rodata_ro();
33@@ -865,6 +866,7 @@ static int noinline init_post(void)
34 ramdisk_execute_command);
35 }
36
37+retry:
38 /*
39 * We try each of these until one succeeds.
40 *
41@@ -877,6 +879,23 @@ static int noinline init_post(void)
42 "defaults...\n", execute_command);
43 }
44 run_init_process("/sbin/init");
45+
46+ if (retry_count > 0) {
47+ retry_count--;
48+ /*
49+ * We haven't found init yet... potentially because the device
50+ * is still being probed. We need to
51+ * - flush keventd and friends
52+ * - wait for the known devices to complete their probing
53+ * - try to mount the root fs again
54+ */
55+ flush_scheduled_work();
56+ while (driver_probe_done() != 0)
57+ msleep(100);
58+ prepare_namespace();
59+ goto retry;
60+ }
61+
62 run_init_process("/etc/init");
63 run_init_process("/bin/init");
64 run_init_process("/bin/sh");
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27/0031-fastboot-make-the-raid-autodetect-code-wait-for-all.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27/0031-fastboot-make-the-raid-autodetect-code-wait-for-all.patch
new file mode 100644
index 0000000000..03b3b82202
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27/0031-fastboot-make-the-raid-autodetect-code-wait-for-all.patch
@@ -0,0 +1,41 @@
1From b52c36a95ed8026b6925fe8595ebcab6921ae62d Mon Sep 17 00:00:00 2001
2From: Arjan van de Ven <arjan@linux.intel.com>
3Date: Sun, 20 Jul 2008 13:07:09 -0700
4Subject: [PATCH] fastboot: make the raid autodetect code wait for all devices to init
5
6The raid autodetect code really needs to have all devices probed before
7it can detect raid arrays; not doing so would give rather messy situations
8where arrays would get detected as degraded while they shouldn't be etc.
9
10This is in preparation of removing the "wait for everything to init"
11code that makes everyone pay, not just raid users.
12
13Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
14---
15 init/do_mounts_md.c | 7 +++++++
16 1 files changed, 7 insertions(+), 0 deletions(-)
17
18diff --git a/init/do_mounts_md.c b/init/do_mounts_md.c
19index 693d246..c0412a9 100644
20--- a/init/do_mounts_md.c
21+++ b/init/do_mounts_md.c
22@@ -267,9 +267,16 @@ __setup("md=", md_setup);
23 void __init md_run_setup(void)
24 {
25 create_dev("/dev/md0", MKDEV(MD_MAJOR, 0));
26+
27 if (raid_noautodetect)
28 printk(KERN_INFO "md: Skipping autodetection of RAID arrays. (raid=noautodetect)\n");
29 else {
30+ /*
31+ * Since we don't want to detect and use half a raid array, we need to
32+ * wait for the known devices to complete their probing
33+ */
34+ while (driver_probe_done() != 0)
35+ msleep(100);
36 int fd = sys_open("/dev/md0", 0, 0);
37 if (fd >= 0) {
38 sys_ioctl(fd, RAID_AUTORUN, raid_autopart);
39--
401.5.4.3
41
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27/0032-fastboot-remove-wait-for-all-devices-before-mounti.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27/0032-fastboot-remove-wait-for-all-devices-before-mounti.patch
new file mode 100644
index 0000000000..c963d4eaf3
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27/0032-fastboot-remove-wait-for-all-devices-before-mounti.patch
@@ -0,0 +1,41 @@
1From 1b5a2bd0602010398cb473d1b821a9f1c1399caf Mon Sep 17 00:00:00 2001
2From: Arjan van de Ven <arjan@linux.intel.com>
3Date: Sun, 20 Jul 2008 13:12:16 -0700
4Subject: [PATCH] fastboot: remove "wait for all devices before mounting root" delay
5
6In the non-initrd case, we wait for all devices to finish their
7probing before we try to mount the rootfs.
8In practice, this means that we end up waiting 2 extra seconds for
9the PS/2 mouse probing even though the root holding device has been
10ready since a long time.
11
12The previous two patches in this series made the RAID autodetect code
13do it's own "wait for probing to be done" code, and added
14"wait and retry" functionality in case the root device isn't actually
15available.
16
17These two changes should make it safe to remove the delay itself,
18and this patch does this. On my test laptop, this reduces the boot time
19by 2 seconds (kernel time goes from 3.9 to 1.9 seconds).
20
21Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
22---
23 init/do_mounts.c | 2 ++
24 1 file changed, 2 insertions(+)
25
26Index: linux-2.6.27/init/do_mounts.c
27===================================================================
28--- linux-2.6.27.orig/init/do_mounts.c 2008-10-14 16:57:34.000000000 +0200
29+++ linux-2.6.27/init/do_mounts.c 2008-10-14 17:02:51.000000000 +0200
30@@ -365,9 +365,11 @@ void __init prepare_namespace(void)
31 ssleep(root_delay);
32 }
33
34+#ifndef CONFIG_FASTBOOT
35 /* wait for the known devices to complete their probing */
36 while (driver_probe_done() != 0)
37 msleep(100);
38+#endif
39
40 md_run_setup();
41
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27/0033-fastboot-make-the-RAID-autostart-code-print-a-messa.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27/0033-fastboot-make-the-RAID-autostart-code-print-a-messa.patch
new file mode 100644
index 0000000000..55c6c1adae
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27/0033-fastboot-make-the-RAID-autostart-code-print-a-messa.patch
@@ -0,0 +1,32 @@
1From 799d0da9e645258b9d1ae11d4aac73c9474906e3 Mon Sep 17 00:00:00 2001
2From: Arjan van de Ven <arjan@linux.intel.com>
3Date: Sun, 20 Jul 2008 16:30:29 -0700
4Subject: [PATCH] fastboot: make the RAID autostart code print a message just before waiting
5
6As requested/suggested by Neil Brown: make the raid code print that it's
7about to wait for probing to be done as well as give a suggestion on how
8to disable the probing if the user doesn't use raid.
9
10Signed-off-by: Arjan van de Ven <arjan@linux.intel.com
11---
12 init/do_mounts_md.c | 4 +++-
13 1 files changed, 3 insertions(+), 1 deletions(-)
14
15diff --git a/init/do_mounts_md.c b/init/do_mounts_md.c
16index c0412a9..1ec5c41 100644
17--- a/init/do_mounts_md.c
18+++ b/init/do_mounts_md.c
19@@ -275,7 +275,9 @@ void __init md_run_setup(void)
20 * Since we don't want to detect and use half a raid array, we need to
21 * wait for the known devices to complete their probing
22 */
23- while (driver_probe_done() != 0)
24+ printk(KERN_INFO "md: Waiting for all devices to be available before autodetect\n");
25+ printk(KERN_INFO "md: If you don't use raid, use raid=noautodetect\n");
26+ while (driver_probe_done() < 0)
27 msleep(100);
28 int fd = sys_open("/dev/md0", 0, 0);
29 if (fd >= 0) {
30--
311.5.4.3
32
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27/0034-fastboot-fix-typo-in-init-Kconfig-text.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27/0034-fastboot-fix-typo-in-init-Kconfig-text.patch
new file mode 100644
index 0000000000..c6f3b8e9ac
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27/0034-fastboot-fix-typo-in-init-Kconfig-text.patch
@@ -0,0 +1,26 @@
1From 1a23ed42e1baf0481cc70c2f71d97b0bf0f1be70 Mon Sep 17 00:00:00 2001
2From: Ingo Molnar <mingo@elte.hu>
3Date: Thu, 31 Jul 2008 12:52:29 +0200
4Subject: [PATCH] fastboot: fix typo in init/Kconfig text
5
6noticed by Randy Dunlap.
7
8Reported-by: Randy Dunlap <randy.dunlap@oracle.com>
9Signed-off-by: Ingo Molnar <mingo@elte.hu>
10---
11 init/Kconfig | 2 +-
12 1 file changed, 1 insertion(+), 1 deletion(-)
13
14Index: linux-2.6.27/init/Kconfig
15===================================================================
16--- linux-2.6.27.orig/init/Kconfig 2008-10-14 17:02:39.000000000 +0200
17+++ linux-2.6.27/init/Kconfig 2008-10-14 17:02:56.000000000 +0200
18@@ -530,7 +530,7 @@ config FASTBOOT
19 The fastboot option will cause the kernel to try to optimize
20 for faster boot.
21
22- This includes doing some of the device initialization asynchronous
23+ This includes doing some of the device initialization asynchronously
24 as well as opportunistically trying to mount the root fs early.
25
26 If unsure, say N.
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27/0035-fastboot-remove-duplicate-unpack_to_rootfs.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27/0035-fastboot-remove-duplicate-unpack_to_rootfs.patch
new file mode 100644
index 0000000000..b8af74eaf2
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27/0035-fastboot-remove-duplicate-unpack_to_rootfs.patch
@@ -0,0 +1,161 @@
1From 8929dda869d51b953c8f300864da62297db8a74e Mon Sep 17 00:00:00 2001
2From: Li, Shaohua <shaohua.li@intel.com>
3Date: Wed, 13 Aug 2008 17:26:01 +0800
4Subject: [PATCH] fastboot: remove duplicate unpack_to_rootfs()
5
6we check if initrd is initramfs first and then do real unpack. The
7check isn't required, we can directly do unpack. If initrd isn't
8initramfs, we can remove garbage. In my laptop, this saves 0.1s boot
9time. This penalizes non-initramfs case, but now initramfs is mostly
10widely used.
11
12Signed-off-by: Shaohua Li <shaohua.li@intel.com>
13Acked-by: Arjan van de Ven <arjan@infradead.org>
14Signed-off-by: Ingo Molnar <mingo@elte.hu>
15---
16 init/initramfs.c | 71 ++++++++++++++++++++++++++++++++++++++++++-----------
17 1 files changed, 56 insertions(+), 15 deletions(-)
18
19diff --git a/init/initramfs.c b/init/initramfs.c
20index 644fc01..da8d030 100644
21--- a/init/initramfs.c
22+++ b/init/initramfs.c
23@@ -5,6 +5,7 @@
24 #include <linux/fcntl.h>
25 #include <linux/delay.h>
26 #include <linux/string.h>
27+#include <linux/dirent.h>
28 #include <linux/syscalls.h>
29
30 static __initdata char *message;
31@@ -121,8 +122,6 @@ static __initdata char *victim;
32 static __initdata unsigned count;
33 static __initdata loff_t this_header, next_header;
34
35-static __initdata int dry_run;
36-
37 static inline void __init eat(unsigned n)
38 {
39 victim += n;
40@@ -183,10 +182,6 @@ static int __init do_header(void)
41 parse_header(collected);
42 next_header = this_header + N_ALIGN(name_len) + body_len;
43 next_header = (next_header + 3) & ~3;
44- if (dry_run) {
45- read_into(name_buf, N_ALIGN(name_len), GotName);
46- return 0;
47- }
48 state = SkipIt;
49 if (name_len <= 0 || name_len > PATH_MAX)
50 return 0;
51@@ -257,8 +252,6 @@ static int __init do_name(void)
52 free_hash();
53 return 0;
54 }
55- if (dry_run)
56- return 0;
57 clean_path(collected, mode);
58 if (S_ISREG(mode)) {
59 int ml = maybe_link();
60@@ -423,10 +416,9 @@ static void __init flush_window(void)
61 outcnt = 0;
62 }
63
64-static char * __init unpack_to_rootfs(char *buf, unsigned len, int check_only)
65+static char * __init unpack_to_rootfs(char *buf, unsigned len)
66 {
67 int written;
68- dry_run = check_only;
69 header_buf = kmalloc(110, GFP_KERNEL);
70 symlink_buf = kmalloc(PATH_MAX + N_ALIGN(PATH_MAX) + 1, GFP_KERNEL);
71 name_buf = kmalloc(N_ALIGN(PATH_MAX), GFP_KERNEL);
72@@ -520,10 +512,57 @@ skip:
73 initrd_end = 0;
74 }
75
76+#define BUF_SIZE 1024
77+static void __init clean_rootfs(void)
78+{
79+ int fd;
80+ void *buf;
81+ struct linux_dirent64 *dirp;
82+ int count;
83+
84+ fd = sys_open("/", O_RDONLY, 0);
85+ WARN_ON(fd < 0);
86+ if (fd < 0)
87+ return;
88+ buf = kzalloc(BUF_SIZE, GFP_KERNEL);
89+ WARN_ON(!buf);
90+ if (!buf) {
91+ sys_close(fd);
92+ return;
93+ }
94+
95+ dirp = buf;
96+ count = sys_getdents64(fd, dirp, BUF_SIZE);
97+ while (count > 0) {
98+ while (count > 0) {
99+ struct stat st;
100+ int ret;
101+
102+ ret = sys_newlstat(dirp->d_name, &st);
103+ WARN_ON_ONCE(ret);
104+ if (!ret) {
105+ if (S_ISDIR(st.st_mode))
106+ sys_rmdir(dirp->d_name);
107+ else
108+ sys_unlink(dirp->d_name);
109+ }
110+
111+ count -= dirp->d_reclen;
112+ dirp = (void *)dirp + dirp->d_reclen;
113+ }
114+ dirp = buf;
115+ memset(buf, 0, BUF_SIZE);
116+ count = sys_getdents64(fd, dirp, BUF_SIZE);
117+ }
118+
119+ sys_close(fd);
120+ kfree(buf);
121+}
122+
123 static int __init populate_rootfs(void)
124 {
125 char *err = unpack_to_rootfs(__initramfs_start,
126- __initramfs_end - __initramfs_start, 0);
127+ __initramfs_end - __initramfs_start);
128 if (err)
129 panic(err);
130 if (initrd_start) {
131@@ -531,13 +570,15 @@ static int __init populate_rootfs(void)
132 int fd;
133 printk(KERN_INFO "checking if image is initramfs...");
134 err = unpack_to_rootfs((char *)initrd_start,
135- initrd_end - initrd_start, 1);
136+ initrd_end - initrd_start);
137 if (!err) {
138 printk(" it is\n");
139- unpack_to_rootfs((char *)initrd_start,
140- initrd_end - initrd_start, 0);
141 free_initrd();
142 return 0;
143+ } else {
144+ clean_rootfs();
145+ unpack_to_rootfs(__initramfs_start,
146+ __initramfs_end - __initramfs_start);
147 }
148 printk("it isn't (%s); looks like an initrd\n", err);
149 fd = sys_open("/initrd.image", O_WRONLY|O_CREAT, 0700);
150@@ -550,7 +591,7 @@ static int __init populate_rootfs(void)
151 #else
152 printk(KERN_INFO "Unpacking initramfs...");
153 err = unpack_to_rootfs((char *)initrd_start,
154- initrd_end - initrd_start, 0);
155+ initrd_end - initrd_start);
156 if (err)
157 panic(err);
158 printk(" done\n");
159--
1601.5.4.3
161
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27/0036-warning-fix-init-do_mounts_md-c.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27/0036-warning-fix-init-do_mounts_md-c.patch
new file mode 100644
index 0000000000..9ba44a892d
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27/0036-warning-fix-init-do_mounts_md-c.patch
@@ -0,0 +1,82 @@
1From fa3038625d7df2a1244c5b753069e7fdf99af3b5 Mon Sep 17 00:00:00 2001
2From: Ingo Molnar <mingo@elte.hu>
3Date: Mon, 18 Aug 2008 12:54:00 +0200
4Subject: [PATCH] warning: fix init do_mounts_md c
5MIME-Version: 1.0
6Content-Type: text/plain; charset=utf-8
7Content-Transfer-Encoding: 8bit
8
9fix warning:
10
11 init/do_mounts_md.c: In function ‘md_run_setup’:
12 init/do_mounts_md.c:282: warning: ISO C90 forbids mixed declarations and code
13
14also, use the opportunity to put the RAID autodetection code
15into a separate function - this also solves a checkpatch style warning.
16
17No code changed:
18
19md5:
20 aa36a35faef371b05f1974ad583bdbbd do_mounts_md.o.before.asm
21 aa36a35faef371b05f1974ad583bdbbd do_mounts_md.o.after.asm
22
23Signed-off-by: Ingo Molnar <mingo@elte.hu>
24---
25 init/do_mounts_md.c | 36 +++++++++++++++++++++---------------
26 1 files changed, 21 insertions(+), 15 deletions(-)
27
28diff --git a/init/do_mounts_md.c b/init/do_mounts_md.c
29index 1ec5c41..c0dfd3c 100644
30--- a/init/do_mounts_md.c
31+++ b/init/do_mounts_md.c
32@@ -264,26 +264,32 @@ static int __init raid_setup(char *str)
33 __setup("raid=", raid_setup);
34 __setup("md=", md_setup);
35
36+static void autodetect_raid(void)
37+{
38+ int fd;
39+
40+ /*
41+ * Since we don't want to detect and use half a raid array, we need to
42+ * wait for the known devices to complete their probing
43+ */
44+ printk(KERN_INFO "md: Waiting for all devices to be available before autodetect\n");
45+ printk(KERN_INFO "md: If you don't use raid, use raid=noautodetect\n");
46+ while (driver_probe_done() < 0)
47+ msleep(100);
48+ fd = sys_open("/dev/md0", 0, 0);
49+ if (fd >= 0) {
50+ sys_ioctl(fd, RAID_AUTORUN, raid_autopart);
51+ sys_close(fd);
52+ }
53+}
54+
55 void __init md_run_setup(void)
56 {
57 create_dev("/dev/md0", MKDEV(MD_MAJOR, 0));
58
59 if (raid_noautodetect)
60 printk(KERN_INFO "md: Skipping autodetection of RAID arrays. (raid=noautodetect)\n");
61- else {
62- /*
63- * Since we don't want to detect and use half a raid array, we need to
64- * wait for the known devices to complete their probing
65- */
66- printk(KERN_INFO "md: Waiting for all devices to be available before autodetect\n");
67- printk(KERN_INFO "md: If you don't use raid, use raid=noautodetect\n");
68- while (driver_probe_done() < 0)
69- msleep(100);
70- int fd = sys_open("/dev/md0", 0, 0);
71- if (fd >= 0) {
72- sys_ioctl(fd, RAID_AUTORUN, raid_autopart);
73- sys_close(fd);
74- }
75- }
76+ else
77+ autodetect_raid();
78 md_setup_drive();
79 }
80--
811.5.4.3
82
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27/0037-init-initramfs.c-unused-function-when-compiling-wit.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27/0037-init-initramfs.c-unused-function-when-compiling-wit.patch
new file mode 100644
index 0000000000..159f988670
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27/0037-init-initramfs.c-unused-function-when-compiling-wit.patch
@@ -0,0 +1,37 @@
1From b4931e6c151acad06b4c12dc7cdb634366d7d27a Mon Sep 17 00:00:00 2001
2From: Steven Noonan <steven@uplinklabs.net>
3Date: Mon, 8 Sep 2008 16:19:10 -0700
4Subject: [PATCH] init/initramfs.c: unused function when compiling without CONFIG_BLK_DEV_RAM
5
6Fixing compiler warning when the kernel isn't compiled with support
7for RAM block devices enabled.
8
9Signed-off-by: Steven Noonan <steven@uplinklabs.net>
10Signed-off-by: Ingo Molnar <mingo@elte.hu>
11---
12 init/initramfs.c | 2 ++
13 1 files changed, 2 insertions(+), 0 deletions(-)
14
15diff --git a/init/initramfs.c b/init/initramfs.c
16index da8d030..2f056e2 100644
17--- a/init/initramfs.c
18+++ b/init/initramfs.c
19@@ -512,6 +512,7 @@ skip:
20 initrd_end = 0;
21 }
22
23+#ifdef CONFIG_BLK_DEV_RAM
24 #define BUF_SIZE 1024
25 static void __init clean_rootfs(void)
26 {
27@@ -558,6 +559,7 @@ static void __init clean_rootfs(void)
28 sys_close(fd);
29 kfree(buf);
30 }
31+#endif
32
33 static int __init populate_rootfs(void)
34 {
35--
361.5.4.3
37
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27/0038-fastboot-fix-blackfin-breakage-due-to-vmlinux.lds-c.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27/0038-fastboot-fix-blackfin-breakage-due-to-vmlinux.lds-c.patch
new file mode 100644
index 0000000000..8d1e3f22f1
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27/0038-fastboot-fix-blackfin-breakage-due-to-vmlinux.lds-c.patch
@@ -0,0 +1,38 @@
1From 5e4f25d1f43991324794657655bbbc43983522a2 Mon Sep 17 00:00:00 2001
2From: Arjan van de Ven <arjan@infradead.org>
3Date: Wed, 10 Sep 2008 08:25:34 -0700
4Subject: [PATCH] fastboot: fix blackfin breakage due to vmlinux.lds change
5
6As reported by Mike Frysinger, the vmlinux.lds changes should
7have used VMLINUX_SYMBOL()...
8
9Reported-by: Mike Frysinger <vapier.adi@gmail.com>
10Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
11Acked-by: Bryan Wu <cooloney@kernel.org>
12Signed-off-by: Ingo Molnar <mingo@elte.hu>
13---
14 include/asm-generic/vmlinux.lds.h | 6 +++---
15 1 files changed, 3 insertions(+), 3 deletions(-)
16
17diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
18index b9be858..ccabc4e 100644
19--- a/include/asm-generic/vmlinux.lds.h
20+++ b/include/asm-generic/vmlinux.lds.h
21@@ -377,11 +377,11 @@
22 *(.initcall5s.init) \
23 *(.initcallrootfs.init) \
24 *(.initcall6s.init) \
25- __async_initcall_start = .; \
26+ VMLINUX_SYMBOL(__async_initcall_start) = .; \
27 *(.initcall6a.init) \
28- __async_initcall_end = .; \
29+ VMLINUX_SYMBOL(__async_initcall_end) = .; \
30 *(.initcall6.init) \
31- __device_initcall_end = .; \
32+ VMLINUX_SYMBOL(__device_initcall_end) = .; \
33 *(.initcall7.init) \
34 *(.initcall7s.init)
35
36--
371.5.4.3
38
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27/0039-Add-a-script-to-visualize-the-kernel-boot-process.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27/0039-Add-a-script-to-visualize-the-kernel-boot-process.patch
new file mode 100644
index 0000000000..6bcaab1087
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27/0039-Add-a-script-to-visualize-the-kernel-boot-process.patch
@@ -0,0 +1,177 @@
1From 77e9695b9d5c9ce761dedc193045d9cb64b8e245 Mon Sep 17 00:00:00 2001
2From: Arjan van de Ven <arjan@linux.intel.com>
3Date: Sat, 13 Sep 2008 09:36:06 -0700
4Subject: [PATCH] Add a script to visualize the kernel boot process / time
5
6When optimizing the kernel boot time, it's very valuable to visualize
7what is going on at which time. In addition, with the fastboot asynchronous
8initcall level, it's very valuable to see which initcall gets run where
9and when.
10
11This patch adds a script to turn a dmesg into a SVG graph (that can be
12shown with tools such as InkScape, Gimp or Firefox) and a small change
13to the initcall code to print the PID of the thread calling the initcall
14(so that the script can work out the parallelism).
15
16Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
17---
18 init/main.c | 1
19 scripts/bootgraph.pl | 138 +++++++++++++++++++++++++++++++++++++++++++++++++++
20 2 files changed, 139 insertions(+)
21 create mode 100644 scripts/bootgraph.pl
22
23Index: linux-2.6.27/init/main.c
24===================================================================
25--- linux-2.6.27.orig/init/main.c 2008-10-14 17:02:46.000000000 +0200
26+++ linux-2.6.27/init/main.c 2008-10-14 17:05:23.000000000 +0200
27@@ -709,6 +709,7 @@ int do_one_initcall(initcall_t fn)
28
29 if (initcall_debug) {
30 printk("calling %pF\n", fn);
31+ printk(" @ %i\n", task_pid_nr(current));
32 t0 = ktime_get();
33 }
34
35Index: linux-2.6.27/scripts/bootgraph.pl
36===================================================================
37--- /dev/null 1970-01-01 00:00:00.000000000 +0000
38+++ linux-2.6.27/scripts/bootgraph.pl 2008-10-14 17:03:34.000000000 +0200
39@@ -0,0 +1,138 @@
40+#!/usr/bin/perl
41+
42+# Copyright 2008, Intel Corporation
43+#
44+# This file is part of the Linux kernel
45+#
46+# This program file is free software; you can redistribute it and/or modify it
47+# under the terms of the GNU General Public License as published by the
48+# Free Software Foundation; version 2 of the License.
49+#
50+# This program is distributed in the hope that it will be useful, but WITHOUT
51+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
52+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
53+# for more details.
54+#
55+# You should have received a copy of the GNU General Public License
56+# along with this program in a file named COPYING; if not, write to the
57+# Free Software Foundation, Inc.,
58+# 51 Franklin Street, Fifth Floor,
59+# Boston, MA 02110-1301 USA
60+#
61+# Authors:
62+# Arjan van de Ven <arjan@linux.intel.com>
63+
64+
65+#
66+# This script turns a dmesg output into a SVG graphic that shows which
67+# functions take how much time. You can view SVG graphics with various
68+# programs, including Inkscape, The Gimp and Firefox.
69+#
70+#
71+# For this script to work, the kernel needs to be compiled with the
72+# CONFIG_PRINTK_TIME configuration option enabled, and with
73+# "initcall_debug" passed on the kernel command line.
74+#
75+# usage:
76+# dmesg | perl scripts/bootgraph.pl > output.svg
77+#
78+
79+my @rows;
80+my %start, %end, %row;
81+my $done = 0;
82+my $rowcount = 0;
83+my $maxtime = 0;
84+my $count = 0;
85+while (<>) {
86+ my $line = $_;
87+ if ($line =~ /([0-9\.]+)\] calling ([a-zA-Z\_]+)\+/) {
88+ my $func = $2;
89+ if ($done == 0) {
90+ $start{$func} = $1;
91+ }
92+ $row{$func} = 1;
93+ if ($line =~ /\@ ([0-9]+)/) {
94+ my $pid = $1;
95+ if (!defined($rows[$pid])) {
96+ $rowcount = $rowcount + 1;
97+ $rows[$pid] = $rowcount;
98+ }
99+ $row{$func} = $rows[$pid];
100+ }
101+ $count = $count + 1;
102+ }
103+
104+ if ($line =~ /([0-9\.]+)\] initcall ([a-zA-Z\_]+)\+.*returned/) {
105+ if ($done == 0) {
106+ $end{$2} = $1;
107+ $maxtime = $1;
108+ }
109+ }
110+ if ($line =~ /Write protecting the/) {
111+ $done = 1;
112+ }
113+}
114+
115+if ($count == 0) {
116+ print "No data found in the dmesg. Make sure CONFIG_PRINTK_TIME is enabled and\n";
117+ print "that initcall_debug is passed on the kernel command line.\n\n";
118+ print "Usage: \n";
119+ print " dmesg | perl scripts/bootgraph.pl > output.svg\n\n";
120+ exit;
121+}
122+
123+print "<?xml version=\"1.0\" standalone=\"no\"?> \n";
124+print "<svg width=\"1000\" height=\"100%\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\">\n";
125+
126+my @styles;
127+
128+$styles[0] = "fill:rgb(0,0,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
129+$styles[1] = "fill:rgb(0,255,0);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
130+$styles[2] = "fill:rgb(255,0,20);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
131+$styles[3] = "fill:rgb(255,255,20);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
132+$styles[4] = "fill:rgb(255,0,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
133+$styles[5] = "fill:rgb(0,255,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
134+$styles[6] = "fill:rgb(0,128,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
135+$styles[7] = "fill:rgb(0,255,128);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
136+$styles[8] = "fill:rgb(255,0,128);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
137+$styles[9] = "fill:rgb(255,255,128);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
138+$styles[10] = "fill:rgb(255,128,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
139+$styles[11] = "fill:rgb(128,255,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
140+
141+my $mult = 950.0 / $maxtime;
142+my $threshold = 0.0500 / $maxtime;
143+my $stylecounter = 0;
144+while (($key,$value) = each %start) {
145+ my $duration = $end{$key} - $start{$key};
146+
147+ if ($duration >= $threshold) {
148+ my $s, $s2, $e, $y;
149+ $s = $value * $mult;
150+ $s2 = $s + 6;
151+ $e = $end{$key} * $mult;
152+ $w = $e - $s;
153+
154+ $y = $row{$key} * 150;
155+ $y2 = $y + 4;
156+
157+ $style = $styles[$stylecounter];
158+ $stylecounter = $stylecounter + 1;
159+ if ($stylecounter > 11) {
160+ $stylecounter = 0;
161+ };
162+
163+ print "<rect x=\"$s\" width=\"$w\" y=\"$y\" height=\"145\" style=\"$style\"/>\n";
164+ print "<text transform=\"translate($s2,$y2) rotate(90)\">$key</text>\n";
165+ }
166+}
167+
168+
169+# print the time line on top
170+my $time = 0.0;
171+while ($time < $maxtime) {
172+ my $s2 = $time * $mult;
173+ print "<text transform=\"translate($s2,89) rotate(90)\">$time</text>\n";
174+ $time = $time + 0.1;
175+}
176+
177+print "</svg>\n";
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27/0040-fastboot-fix-issues-and-improve-output-of-bootgraph.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27/0040-fastboot-fix-issues-and-improve-output-of-bootgraph.patch
new file mode 100644
index 0000000000..0daba9d2cf
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27/0040-fastboot-fix-issues-and-improve-output-of-bootgraph.patch
@@ -0,0 +1,91 @@
1From 5470e09b98074974316bbf98c8b8da01d670c2a4 Mon Sep 17 00:00:00 2001
2From: Arjan van de Ven <arjan@linux.intel.com>
3Date: Sun, 14 Sep 2008 15:30:52 -0700
4Subject: [PATCH] fastboot: fix issues and improve output of bootgraph.pl
5
6David Sanders reported some issues with bootgraph.pl's display
7of his sytems bootup; this commit fixes these by scaling the graph
8not from 0 - end time but from the first initcall to the end time;
9the minimum display size etc also now need to scale with this, as does
10the axis display.
11
12Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
13---
14 scripts/bootgraph.pl | 25 +++++++++++++++++--------
15 1 files changed, 17 insertions(+), 8 deletions(-)
16
17diff --git a/scripts/bootgraph.pl b/scripts/bootgraph.pl
18index d459b8b..4e5f4ab 100644
19--- a/scripts/bootgraph.pl
20+++ b/scripts/bootgraph.pl
21@@ -42,6 +42,7 @@ my %start, %end, %row;
22 my $done = 0;
23 my $rowcount = 0;
24 my $maxtime = 0;
25+my $firsttime = 100;
26 my $count = 0;
27 while (<>) {
28 my $line = $_;
29@@ -49,6 +50,9 @@ while (<>) {
30 my $func = $2;
31 if ($done == 0) {
32 $start{$func} = $1;
33+ if ($1 < $firsttime) {
34+ $firsttime = $1;
35+ }
36 }
37 $row{$func} = 1;
38 if ($line =~ /\@ ([0-9]+)/) {
39@@ -71,6 +75,9 @@ while (<>) {
40 if ($line =~ /Write protecting the/) {
41 $done = 1;
42 }
43+ if ($line =~ /Freeing unused kernel memory/) {
44+ $done = 1;
45+ }
46 }
47
48 if ($count == 0) {
49@@ -99,17 +106,17 @@ $styles[9] = "fill:rgb(255,255,128);fill-opacity:0.5;stroke-width:1;stroke:rgb(0
50 $styles[10] = "fill:rgb(255,128,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
51 $styles[11] = "fill:rgb(128,255,255);fill-opacity:0.5;stroke-width:1;stroke:rgb(0,0,0)";
52
53-my $mult = 950.0 / $maxtime;
54-my $threshold = 0.0500 / $maxtime;
55+my $mult = 950.0 / ($maxtime - $firsttime);
56+my $threshold = ($maxtime - $firsttime) / 60.0;
57 my $stylecounter = 0;
58 while (($key,$value) = each %start) {
59 my $duration = $end{$key} - $start{$key};
60
61 if ($duration >= $threshold) {
62 my $s, $s2, $e, $y;
63- $s = $value * $mult;
64+ $s = ($value - $firsttime) * $mult;
65 $s2 = $s + 6;
66- $e = $end{$key} * $mult;
67+ $e = ($end{$key} - $firsttime) * $mult;
68 $w = $e - $s;
69
70 $y = $row{$key} * 150;
71@@ -128,11 +135,13 @@ while (($key,$value) = each %start) {
72
73
74 # print the time line on top
75-my $time = 0.0;
76+my $time = $firsttime;
77+my $step = ($maxtime - $firsttime) / 15;
78 while ($time < $maxtime) {
79- my $s2 = $time * $mult;
80- print "<text transform=\"translate($s2,89) rotate(90)\">$time</text>\n";
81- $time = $time + 0.1;
82+ my $s2 = ($time - $firsttime) * $mult;
83+ my $tm = int($time * 100) / 100.0;
84+ print "<text transform=\"translate($s2,89) rotate(90)\">$tm</text>\n";
85+ $time = $time + $step;
86 }
87
88 print "</svg>\n";
89--
901.5.4.3
91
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27/0041-r8169-8101e.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27/0041-r8169-8101e.patch
new file mode 100644
index 0000000000..781c9a127e
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27/0041-r8169-8101e.patch
@@ -0,0 +1,940 @@
1From 771c0d99c0ab3ca7f1a9bc400e8259171b518d5f Mon Sep 17 00:00:00 2001
2From: Francois Romieu <romieu@fr.zoreil.com>
3Date: Thu, 21 Aug 2008 23:20:40 +0200
4Subject: [PATCH] r8169: fix RxMissed register access
5
6- the register location is defined for the 8169 chipset only and
7 there is no 8169 beyond RTL_GIGA_MAC_VER_06
8- only the lower 3 bytes of the register are valid
9
10Fixes:
111. http://bugzilla.kernel.org/show_bug.cgi?id=10180
122. http://bugzilla.kernel.org/show_bug.cgi?id=11062 (bits of)
13
14Tested by Hermann Gausterer and Adam Huffman.
15
16Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
17Cc: Edward Hsu <edward_hsu@realtek.com.tw>
18---
19 drivers/net/r8169.c | 25 ++++++++++++++-----------
20 1 files changed, 14 insertions(+), 11 deletions(-)
21
22diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
23index 0f6f974..4190ee7 100644
24--- a/drivers/net/r8169.c
25+++ b/drivers/net/r8169.c
26@@ -2099,8 +2099,6 @@ static void rtl_hw_start_8168(struct net_device *dev)
27
28 RTL_R8(IntrMask);
29
30- RTL_W32(RxMissed, 0);
31-
32 rtl_set_rx_mode(dev);
33
34 RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
35@@ -2143,8 +2141,6 @@ static void rtl_hw_start_8101(struct net_device *dev)
36
37 RTL_R8(IntrMask);
38
39- RTL_W32(RxMissed, 0);
40-
41 rtl_set_rx_mode(dev);
42
43 RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
44@@ -2922,6 +2918,17 @@ static int rtl8169_poll(struct napi_struct *napi, int budget)
45 return work_done;
46 }
47
48+static void rtl8169_rx_missed(struct net_device *dev, void __iomem *ioaddr)
49+{
50+ struct rtl8169_private *tp = netdev_priv(dev);
51+
52+ if (tp->mac_version > RTL_GIGA_MAC_VER_06)
53+ return;
54+
55+ dev->stats.rx_missed_errors += (RTL_R32(RxMissed) & 0xffffff);
56+ RTL_W32(RxMissed, 0);
57+}
58+
59 static void rtl8169_down(struct net_device *dev)
60 {
61 struct rtl8169_private *tp = netdev_priv(dev);
62@@ -2939,9 +2946,7 @@ core_down:
63
64 rtl8169_asic_down(ioaddr);
65
66- /* Update the error counts. */
67- dev->stats.rx_missed_errors += RTL_R32(RxMissed);
68- RTL_W32(RxMissed, 0);
69+ rtl8169_rx_missed(dev, ioaddr);
70
71 spin_unlock_irq(&tp->lock);
72
73@@ -3063,8 +3068,7 @@ static struct net_device_stats *rtl8169_get_stats(struct net_device *dev)
74
75 if (netif_running(dev)) {
76 spin_lock_irqsave(&tp->lock, flags);
77- dev->stats.rx_missed_errors += RTL_R32(RxMissed);
78- RTL_W32(RxMissed, 0);
79+ rtl8169_rx_missed(dev, ioaddr);
80 spin_unlock_irqrestore(&tp->lock, flags);
81 }
82
83@@ -3089,8 +3093,7 @@ static int rtl8169_suspend(struct pci_dev *pdev, pm_message_t state)
84
85 rtl8169_asic_down(ioaddr);
86
87- dev->stats.rx_missed_errors += RTL_R32(RxMissed);
88- RTL_W32(RxMissed, 0);
89+ rtl8169_rx_missed(dev, ioaddr);
90
91 spin_unlock_irq(&tp->lock);
92
93--
941.5.3.3
95
96From 6ee4bc96d446a9c466a18b715c7ab2d662c03ebd Mon Sep 17 00:00:00 2001
97From: Francois Romieu <romieu@fr.zoreil.com>
98Date: Sat, 26 Jul 2008 14:26:06 +0200
99Subject: [PATCH] r8169: get ethtool settings through the generic mii helper
100
101It avoids to report unsupported link capabilities with
102the fast-ethernet only 8101/8102.
103
104Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
105Tested-by: Martin Capitanio <martin@capitanio.org>
106Fixed-by: Ivan Vecera <ivecera@redhat.com>
107Cc: Edward Hsu <edward_hsu@realtek.com.tw>
108---
109 drivers/net/r8169.c | 99 +++++++++++++++++++++++---------------------------
110 1 files changed, 46 insertions(+), 53 deletions(-)
111
112diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
113index 4190ee7..7e026a6 100644
114--- a/drivers/net/r8169.c
115+++ b/drivers/net/r8169.c
116@@ -370,8 +370,9 @@ struct ring_info {
117 };
118
119 enum features {
120- RTL_FEATURE_WOL = (1 << 0),
121- RTL_FEATURE_MSI = (1 << 1),
122+ RTL_FEATURE_WOL = (1 << 0),
123+ RTL_FEATURE_MSI = (1 << 1),
124+ RTL_FEATURE_GMII = (1 << 2),
125 };
126
127 struct rtl8169_private {
128@@ -406,13 +407,15 @@ struct rtl8169_private {
129 struct vlan_group *vlgrp;
130 #endif
131 int (*set_speed)(struct net_device *, u8 autoneg, u16 speed, u8 duplex);
132- void (*get_settings)(struct net_device *, struct ethtool_cmd *);
133+ int (*get_settings)(struct net_device *, struct ethtool_cmd *);
134 void (*phy_reset_enable)(void __iomem *);
135 void (*hw_start)(struct net_device *);
136 unsigned int (*phy_reset_pending)(void __iomem *);
137 unsigned int (*link_ok)(void __iomem *);
138 struct delayed_work task;
139 unsigned features;
140+
141+ struct mii_if_info mii;
142 };
143
144 MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>");
145@@ -482,6 +485,23 @@ static int mdio_read(void __iomem *ioaddr, int reg_addr)
146 return value;
147 }
148
149+static void rtl_mdio_write(struct net_device *dev, int phy_id, int location,
150+ int val)
151+{
152+ struct rtl8169_private *tp = netdev_priv(dev);
153+ void __iomem *ioaddr = tp->mmio_addr;
154+
155+ mdio_write(ioaddr, location, val);
156+}
157+
158+static int rtl_mdio_read(struct net_device *dev, int phy_id, int location)
159+{
160+ struct rtl8169_private *tp = netdev_priv(dev);
161+ void __iomem *ioaddr = tp->mmio_addr;
162+
163+ return mdio_read(ioaddr, location);
164+}
165+
166 static void rtl8169_irq_mask_and_ack(void __iomem *ioaddr)
167 {
168 RTL_W16(IntrMask, 0x0000);
169@@ -850,7 +870,7 @@ static int rtl8169_rx_vlan_skb(struct rtl8169_private *tp, struct RxDesc *desc,
170
171 #endif
172
173-static void rtl8169_gset_tbi(struct net_device *dev, struct ethtool_cmd *cmd)
174+static int rtl8169_gset_tbi(struct net_device *dev, struct ethtool_cmd *cmd)
175 {
176 struct rtl8169_private *tp = netdev_priv(dev);
177 void __iomem *ioaddr = tp->mmio_addr;
178@@ -867,65 +887,29 @@ static void rtl8169_gset_tbi(struct net_device *dev, struct ethtool_cmd *cmd)
179
180 cmd->speed = SPEED_1000;
181 cmd->duplex = DUPLEX_FULL; /* Always set */
182+
183+ return 0;
184 }
185
186-static void rtl8169_gset_xmii(struct net_device *dev, struct ethtool_cmd *cmd)
187+static int rtl8169_gset_xmii(struct net_device *dev, struct ethtool_cmd *cmd)
188 {
189 struct rtl8169_private *tp = netdev_priv(dev);
190- void __iomem *ioaddr = tp->mmio_addr;
191- u8 status;
192-
193- cmd->supported = SUPPORTED_10baseT_Half |
194- SUPPORTED_10baseT_Full |
195- SUPPORTED_100baseT_Half |
196- SUPPORTED_100baseT_Full |
197- SUPPORTED_1000baseT_Full |
198- SUPPORTED_Autoneg |
199- SUPPORTED_TP;
200-
201- cmd->autoneg = 1;
202- cmd->advertising = ADVERTISED_TP | ADVERTISED_Autoneg;
203-
204- if (tp->phy_auto_nego_reg & ADVERTISE_10HALF)
205- cmd->advertising |= ADVERTISED_10baseT_Half;
206- if (tp->phy_auto_nego_reg & ADVERTISE_10FULL)
207- cmd->advertising |= ADVERTISED_10baseT_Full;
208- if (tp->phy_auto_nego_reg & ADVERTISE_100HALF)
209- cmd->advertising |= ADVERTISED_100baseT_Half;
210- if (tp->phy_auto_nego_reg & ADVERTISE_100FULL)
211- cmd->advertising |= ADVERTISED_100baseT_Full;
212- if (tp->phy_1000_ctrl_reg & ADVERTISE_1000FULL)
213- cmd->advertising |= ADVERTISED_1000baseT_Full;
214-
215- status = RTL_R8(PHYstatus);
216-
217- if (status & _1000bpsF)
218- cmd->speed = SPEED_1000;
219- else if (status & _100bps)
220- cmd->speed = SPEED_100;
221- else if (status & _10bps)
222- cmd->speed = SPEED_10;
223-
224- if (status & TxFlowCtrl)
225- cmd->advertising |= ADVERTISED_Asym_Pause;
226- if (status & RxFlowCtrl)
227- cmd->advertising |= ADVERTISED_Pause;
228-
229- cmd->duplex = ((status & _1000bpsF) || (status & FullDup)) ?
230- DUPLEX_FULL : DUPLEX_HALF;
231+
232+ return mii_ethtool_gset(&tp->mii, cmd);
233 }
234
235 static int rtl8169_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
236 {
237 struct rtl8169_private *tp = netdev_priv(dev);
238 unsigned long flags;
239+ int rc;
240
241 spin_lock_irqsave(&tp->lock, flags);
242
243- tp->get_settings(dev, cmd);
244+ rc = tp->get_settings(dev, cmd);
245
246 spin_unlock_irqrestore(&tp->lock, flags);
247- return 0;
248+ return rc;
249 }
250
251 static void rtl8169_get_regs(struct net_device *dev, struct ethtool_regs *regs,
252@@ -1513,7 +1497,7 @@ static const struct rtl_cfg_info {
253 unsigned int align;
254 u16 intr_event;
255 u16 napi_event;
256- unsigned msi;
257+ unsigned features;
258 } rtl_cfg_infos [] = {
259 [RTL_CFG_0] = {
260 .hw_start = rtl_hw_start_8169,
261@@ -1522,7 +1506,7 @@ static const struct rtl_cfg_info {
262 .intr_event = SYSErr | LinkChg | RxOverflow |
263 RxFIFOOver | TxErr | TxOK | RxOK | RxErr,
264 .napi_event = RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow,
265- .msi = 0
266+ .features = RTL_FEATURE_GMII
267 },
268 [RTL_CFG_1] = {
269 .hw_start = rtl_hw_start_8168,
270@@ -1531,7 +1515,7 @@ static const struct rtl_cfg_info {
271 .intr_event = SYSErr | LinkChg | RxOverflow |
272 TxErr | TxOK | RxOK | RxErr,
273 .napi_event = TxErr | TxOK | RxOK | RxOverflow,
274- .msi = RTL_FEATURE_MSI
275+ .features = RTL_FEATURE_GMII | RTL_FEATURE_MSI
276 },
277 [RTL_CFG_2] = {
278 .hw_start = rtl_hw_start_8101,
279@@ -1540,7 +1524,7 @@ static const struct rtl_cfg_info {
280 .intr_event = SYSErr | LinkChg | RxOverflow | PCSTimeout |
281 RxFIFOOver | TxErr | TxOK | RxOK | RxErr,
282 .napi_event = RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow,
283- .msi = RTL_FEATURE_MSI
284+ .features = RTL_FEATURE_MSI
285 }
286 };
287
288@@ -1552,7 +1536,7 @@ static unsigned rtl_try_msi(struct pci_dev *pdev, void __iomem *ioaddr,
289 u8 cfg2;
290
291 cfg2 = RTL_R8(Config2) & ~MSIEnable;
292- if (cfg->msi) {
293+ if (cfg->features & RTL_FEATURE_MSI) {
294 if (pci_enable_msi(pdev)) {
295 dev_info(&pdev->dev, "no MSI. Back to INTx.\n");
296 } else {
297@@ -1578,6 +1562,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
298 const struct rtl_cfg_info *cfg = rtl_cfg_infos + ent->driver_data;
299 const unsigned int region = cfg->region;
300 struct rtl8169_private *tp;
301+ struct mii_if_info *mii;
302 struct net_device *dev;
303 void __iomem *ioaddr;
304 unsigned int i;
305@@ -1602,6 +1587,14 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
306 tp->pci_dev = pdev;
307 tp->msg_enable = netif_msg_init(debug.msg_enable, R8169_MSG_DEFAULT);
308
309+ mii = &tp->mii;
310+ mii->dev = dev;
311+ mii->mdio_read = rtl_mdio_read;
312+ mii->mdio_write = rtl_mdio_write;
313+ mii->phy_id_mask = 0x1f;
314+ mii->reg_num_mask = 0x1f;
315+ mii->supports_gmii = !!(cfg->features & RTL_FEATURE_GMII);
316+
317 /* enable device (incl. PCI PM wakeup and hotplug setup) */
318 rc = pci_enable_device(pdev);
319 if (rc < 0) {
320--
3211.5.3.3
322
323From ef60b2a38e223a331e13ef503aee7cd5d4d5c12c Mon Sep 17 00:00:00 2001
324From: Hugh Dickins <hugh@veritas.com>
325Date: Mon, 8 Sep 2008 21:49:01 +0100
326Subject: [PATCH] r8169: select MII in Kconfig
327
328drivers/built-in.o: In function `rtl8169_gset_xmii':
329r8169.c:(.text+0x82259): undefined reference to `mii_ethtool_gset'
330suggests that the r8169 driver now needs to select MII.
331
332Signed-off-by: Hugh Dickins <hugh@veritas.com>
333Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
334Cc: Edward Hsu <edward_hsu@realtek.com.tw>
335---
336 drivers/net/Kconfig | 1 +
337 1 files changed, 1 insertions(+), 0 deletions(-)
338
339diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
340index 4a11296..60a0453 100644
341--- a/drivers/net/Kconfig
342+++ b/drivers/net/Kconfig
343@@ -2046,6 +2046,7 @@ config R8169
344 tristate "Realtek 8169 gigabit ethernet support"
345 depends on PCI
346 select CRC32
347+ select MII
348 ---help---
349 Say Y here if you have a Realtek 8169 PCI Gigabit Ethernet adapter.
350
351--
3521.5.3.3
353
354From bca31864fca6004c4a4a9bd549e95c93b3c3bb10 Mon Sep 17 00:00:00 2001
355From: Francois Romieu <romieu@fr.zoreil.com>
356Date: Sat, 2 Aug 2008 15:50:02 +0200
357Subject: [PATCH] r8169: Tx performance tweak helper
358
359Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
360Cc: Edward Hsu <edward_hsu@realtek.com.tw>
361---
362 drivers/net/r8169.c | 15 ++++++++++-----
363 1 files changed, 10 insertions(+), 5 deletions(-)
364
365diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
366index 7e026a6..eea96fb 100644
367--- a/drivers/net/r8169.c
368+++ b/drivers/net/r8169.c
369@@ -2054,12 +2054,20 @@ static void rtl_hw_start_8169(struct net_device *dev)
370 RTL_W16(IntrMask, tp->intr_event);
371 }
372
373+static void rtl_tx_performance_tweak(struct pci_dev *pdev, u8 force)
374+{
375+ u8 ctl;
376+
377+ pci_read_config_byte(pdev, 0x69, &ctl);
378+ ctl = (ctl & ~0x70) | force;
379+ pci_write_config_byte(pdev, 0x69, ctl);
380+}
381+
382 static void rtl_hw_start_8168(struct net_device *dev)
383 {
384 struct rtl8169_private *tp = netdev_priv(dev);
385 void __iomem *ioaddr = tp->mmio_addr;
386 struct pci_dev *pdev = tp->pci_dev;
387- u8 ctl;
388
389 RTL_W8(Cfg9346, Cfg9346_Unlock);
390
391@@ -2073,10 +2081,7 @@ static void rtl_hw_start_8168(struct net_device *dev)
392
393 RTL_W16(CPlusCmd, tp->cp_cmd);
394
395- /* Tx performance tweak. */
396- pci_read_config_byte(pdev, 0x69, &ctl);
397- ctl = (ctl & ~0x70) | 0x50;
398- pci_write_config_byte(pdev, 0x69, ctl);
399+ rtl_tx_performance_tweak(pdev, 0x50);
400
401 RTL_W16(IntrMitigate, 0x5151);
402
403--
4041.5.3.3
405
406From 7a929ae7d5a3618f56bf1ccaf8c62df628e820aa Mon Sep 17 00:00:00 2001
407From: Francois Romieu <romieu@fr.zoreil.com>
408Date: Sat, 5 Jul 2008 00:21:15 +0200
409Subject: [PATCH] r8169: use pci_find_capability for the PCI-E features
410
411Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
412Cc: Edward Hsu <edward_hsu@realtek.com.tw>
413---
414 drivers/net/r8169.c | 32 ++++++++++++++++++++++++--------
415 1 files changed, 24 insertions(+), 8 deletions(-)
416
417diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
418index eea96fb..5c00522 100644
419--- a/drivers/net/r8169.c
420+++ b/drivers/net/r8169.c
421@@ -61,6 +61,7 @@ static const int multicast_filter_limit = 32;
422 /* MAC address length */
423 #define MAC_ADDR_LEN 6
424
425+#define MAX_READ_REQUEST_SHIFT 12
426 #define RX_FIFO_THRESH 7 /* 7 means NO threshold, Rx buffer level before first PCI xfer. */
427 #define RX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */
428 #define TX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */
429@@ -412,6 +413,7 @@ struct rtl8169_private {
430 void (*hw_start)(struct net_device *);
431 unsigned int (*phy_reset_pending)(void __iomem *);
432 unsigned int (*link_ok)(void __iomem *);
433+ int pcie_cap;
434 struct delayed_work task;
435 unsigned features;
436
437@@ -1663,6 +1665,10 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
438 goto err_out_free_res_4;
439 }
440
441+ tp->pcie_cap = pci_find_capability(pdev, PCI_CAP_ID_EXP);
442+ if (!tp->pcie_cap && netif_msg_probe(tp))
443+ dev_info(&pdev->dev, "no PCI Express capability\n");
444+
445 /* Unneeded ? Don't mess with Mrs. Murphy. */
446 rtl8169_irq_mask_and_ack(ioaddr);
447
448@@ -2054,13 +2060,19 @@ static void rtl_hw_start_8169(struct net_device *dev)
449 RTL_W16(IntrMask, tp->intr_event);
450 }
451
452-static void rtl_tx_performance_tweak(struct pci_dev *pdev, u8 force)
453+static void rtl_tx_performance_tweak(struct pci_dev *pdev, u16 force)
454 {
455- u8 ctl;
456+ struct net_device *dev = pci_get_drvdata(pdev);
457+ struct rtl8169_private *tp = netdev_priv(dev);
458+ int cap = tp->pcie_cap;
459+
460+ if (cap) {
461+ u16 ctl;
462
463- pci_read_config_byte(pdev, 0x69, &ctl);
464- ctl = (ctl & ~0x70) | force;
465- pci_write_config_byte(pdev, 0x69, ctl);
466+ pci_read_config_word(pdev, cap + PCI_EXP_DEVCTL, &ctl);
467+ ctl = (ctl & ~PCI_EXP_DEVCTL_READRQ) | force;
468+ pci_write_config_word(pdev, cap + PCI_EXP_DEVCTL, ctl);
469+ }
470 }
471
472 static void rtl_hw_start_8168(struct net_device *dev)
473@@ -2081,7 +2093,7 @@ static void rtl_hw_start_8168(struct net_device *dev)
474
475 RTL_W16(CPlusCmd, tp->cp_cmd);
476
477- rtl_tx_performance_tweak(pdev, 0x50);
478+ rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
479
480 RTL_W16(IntrMitigate, 0x5151);
481
482@@ -2114,8 +2126,12 @@ static void rtl_hw_start_8101(struct net_device *dev)
483
484 if ((tp->mac_version == RTL_GIGA_MAC_VER_13) ||
485 (tp->mac_version == RTL_GIGA_MAC_VER_16)) {
486- pci_write_config_word(pdev, 0x68, 0x00);
487- pci_write_config_word(pdev, 0x69, 0x08);
488+ int cap = tp->pcie_cap;
489+
490+ if (cap) {
491+ pci_write_config_word(pdev, cap + PCI_EXP_DEVCTL,
492+ PCI_EXP_DEVCTL_NOSNOOP_EN);
493+ }
494 }
495
496 RTL_W8(Cfg9346, Cfg9346_Unlock);
497--
4981.5.3.3
499
500From ba648bdcbca93084360d348eb43dde4b19b2489e Mon Sep 17 00:00:00 2001
501From: Francois Romieu <romieu@fr.zoreil.com>
502Date: Sun, 1 Jun 2008 22:37:49 +0200
503Subject: [PATCH] r8169: add 8168/8101 registers description
504
505Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
506Cc: Edward Hsu <edward_hsu@realtek.com.tw>
507---
508 drivers/net/r8169.c | 47 +++++++++++++++++++++++++++++++++++++++++++----
509 1 files changed, 43 insertions(+), 4 deletions(-)
510
511diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
512index 5c00522..0b8db03 100644
513--- a/drivers/net/r8169.c
514+++ b/drivers/net/r8169.c
515@@ -197,9 +197,6 @@ enum rtl_registers {
516 Config5 = 0x56,
517 MultiIntr = 0x5c,
518 PHYAR = 0x60,
519- TBICSR = 0x64,
520- TBI_ANAR = 0x68,
521- TBI_LPAR = 0x6a,
522 PHYstatus = 0x6c,
523 RxMaxSize = 0xda,
524 CPlusCmd = 0xe0,
525@@ -213,6 +210,32 @@ enum rtl_registers {
526 FuncForceEvent = 0xfc,
527 };
528
529+enum rtl8110_registers {
530+ TBICSR = 0x64,
531+ TBI_ANAR = 0x68,
532+ TBI_LPAR = 0x6a,
533+};
534+
535+enum rtl8168_8101_registers {
536+ CSIDR = 0x64,
537+ CSIAR = 0x68,
538+#define CSIAR_FLAG 0x80000000
539+#define CSIAR_WRITE_CMD 0x80000000
540+#define CSIAR_BYTE_ENABLE 0x0f
541+#define CSIAR_BYTE_ENABLE_SHIFT 12
542+#define CSIAR_ADDR_MASK 0x0fff
543+
544+ EPHYAR = 0x80,
545+#define EPHYAR_FLAG 0x80000000
546+#define EPHYAR_WRITE_CMD 0x80000000
547+#define EPHYAR_REG_MASK 0x1f
548+#define EPHYAR_REG_SHIFT 16
549+#define EPHYAR_DATA_MASK 0xffff
550+ DBG_REG = 0xd1,
551+#define FIX_NAK_1 (1 << 4)
552+#define FIX_NAK_2 (1 << 3)
553+};
554+
555 enum rtl_register_content {
556 /* InterruptStatusBits */
557 SYSErr = 0x8000,
558@@ -266,7 +289,13 @@ enum rtl_register_content {
559 TxDMAShift = 8, /* DMA burst value (0-7) is shift this many bits */
560
561 /* Config1 register p.24 */
562+ LEDS1 = (1 << 7),
563+ LEDS0 = (1 << 6),
564 MSIEnable = (1 << 5), /* Enable Message Signaled Interrupt */
565+ Speed_down = (1 << 4),
566+ MEMMAP = (1 << 3),
567+ IOMAP = (1 << 2),
568+ VPD = (1 << 1),
569 PMEnable = (1 << 0), /* Power Management Enable */
570
571 /* Config2 register p. 25 */
572@@ -276,6 +305,7 @@ enum rtl_register_content {
573 /* Config3 register p.25 */
574 MagicPacket = (1 << 5), /* Wake up when receives a Magic Packet */
575 LinkUp = (1 << 4), /* Wake up when the cable connection is re-established */
576+ Beacon_en = (1 << 0), /* 8168 only. Reserved in the 8168b */
577
578 /* Config5 register p.27 */
579 BWF = (1 << 6), /* Accept Broadcast wakeup frame */
580@@ -293,7 +323,16 @@ enum rtl_register_content {
581 TBINwComplete = 0x01000000,
582
583 /* CPlusCmd p.31 */
584- PktCntrDisable = (1 << 7), // 8168
585+ EnableBist = (1 << 15), // 8168 8101
586+ Mac_dbgo_oe = (1 << 14), // 8168 8101
587+ Normal_mode = (1 << 13), // unused
588+ Force_half_dup = (1 << 12), // 8168 8101
589+ Force_rxflow_en = (1 << 11), // 8168 8101
590+ Force_txflow_en = (1 << 10), // 8168 8101
591+ Cxpl_dbg_sel = (1 << 9), // 8168 8101
592+ ASF = (1 << 8), // 8168 8101
593+ PktCntrDisable = (1 << 7), // 8168 8101
594+ Mac_dbgo_sel = 0x001c, // 8168
595 RxVlan = (1 << 6),
596 RxChkSum = (1 << 5),
597 PCIDAC = (1 << 4),
598--
5991.5.3.3
600
601From 61650c9e3d637b0990d9f26b1421ac4b55f5c744 Mon Sep 17 00:00:00 2001
602From: Francois Romieu <romieu@fr.zoreil.com>
603Date: Sat, 2 Aug 2008 20:44:13 +0200
604Subject: [PATCH] r8169: add hw start helpers for the 8168 and the 8101
605
606This commit triggers three 'defined but not used' warnings but
607I prefer avoiding to tie these helpers to a specific change in
608the hw start sequences of the 8168 or of the 8101.
609
610Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
611Cc: Edward Hsu <edward_hsu@realtek.com.tw>
612---
613 drivers/net/r8169.c | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++
614 1 files changed, 96 insertions(+), 0 deletions(-)
615
616diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
617index 0b8db03..52eba5c 100644
618--- a/drivers/net/r8169.c
619+++ b/drivers/net/r8169.c
620@@ -526,6 +526,11 @@ static int mdio_read(void __iomem *ioaddr, int reg_addr)
621 return value;
622 }
623
624+static void mdio_patch(void __iomem *ioaddr, int reg_addr, int value)
625+{
626+ mdio_write(ioaddr, reg_addr, mdio_read(ioaddr, reg_addr) | value);
627+}
628+
629 static void rtl_mdio_write(struct net_device *dev, int phy_id, int location,
630 int val)
631 {
632@@ -543,6 +548,72 @@ static int rtl_mdio_read(struct net_device *dev, int phy_id, int location)
633 return mdio_read(ioaddr, location);
634 }
635
636+static void rtl_ephy_write(void __iomem *ioaddr, int reg_addr, int value)
637+{
638+ unsigned int i;
639+
640+ RTL_W32(EPHYAR, EPHYAR_WRITE_CMD | (value & EPHYAR_DATA_MASK) |
641+ (reg_addr & EPHYAR_REG_MASK) << EPHYAR_REG_SHIFT);
642+
643+ for (i = 0; i < 100; i++) {
644+ if (!(RTL_R32(EPHYAR) & EPHYAR_FLAG))
645+ break;
646+ udelay(10);
647+ }
648+}
649+
650+static u16 rtl_ephy_read(void __iomem *ioaddr, int reg_addr)
651+{
652+ u16 value = 0xffff;
653+ unsigned int i;
654+
655+ RTL_W32(EPHYAR, (reg_addr & EPHYAR_REG_MASK) << EPHYAR_REG_SHIFT);
656+
657+ for (i = 0; i < 100; i++) {
658+ if (RTL_R32(EPHYAR) & EPHYAR_FLAG) {
659+ value = RTL_R32(EPHYAR) & EPHYAR_DATA_MASK;
660+ break;
661+ }
662+ udelay(10);
663+ }
664+
665+ return value;
666+}
667+
668+static void rtl_csi_write(void __iomem *ioaddr, int addr, int value)
669+{
670+ unsigned int i;
671+
672+ RTL_W32(CSIDR, value);
673+ RTL_W32(CSIAR, CSIAR_WRITE_CMD | (addr & CSIAR_ADDR_MASK) |
674+ CSIAR_BYTE_ENABLE << CSIAR_BYTE_ENABLE_SHIFT);
675+
676+ for (i = 0; i < 100; i++) {
677+ if (!(RTL_R32(CSIAR) & CSIAR_FLAG))
678+ break;
679+ udelay(10);
680+ }
681+}
682+
683+static u32 rtl_csi_read(void __iomem *ioaddr, int addr)
684+{
685+ u32 value = ~0x00;
686+ unsigned int i;
687+
688+ RTL_W32(CSIAR, (addr & CSIAR_ADDR_MASK) |
689+ CSIAR_BYTE_ENABLE << CSIAR_BYTE_ENABLE_SHIFT);
690+
691+ for (i = 0; i < 100; i++) {
692+ if (RTL_R32(CSIAR) & CSIAR_FLAG) {
693+ value = RTL_R32(CSIDR);
694+ break;
695+ }
696+ udelay(10);
697+ }
698+
699+ return value;
700+}
701+
702 static void rtl8169_irq_mask_and_ack(void __iomem *ioaddr)
703 {
704 RTL_W16(IntrMask, 0x0000);
705@@ -2114,6 +2185,31 @@ static void rtl_tx_performance_tweak(struct pci_dev *pdev, u16 force)
706 }
707 }
708
709+static void rtl_csi_access_enable(void __iomem *ioaddr)
710+{
711+ u32 csi;
712+
713+ csi = rtl_csi_read(ioaddr, 0x070c) & 0x00ffffff;
714+ rtl_csi_write(ioaddr, 0x070c, csi | 0x27000000);
715+}
716+
717+struct ephy_info {
718+ unsigned int offset;
719+ u16 mask;
720+ u16 bits;
721+};
722+
723+static void rtl_ephy_init(void __iomem *ioaddr, struct ephy_info *e, int len)
724+{
725+ u16 w;
726+
727+ while (len-- > 0) {
728+ w = (rtl_ephy_read(ioaddr, e->offset) & ~e->mask) | e->bits;
729+ rtl_ephy_write(ioaddr, e->offset, w);
730+ e++;
731+ }
732+}
733+
734 static void rtl_hw_start_8168(struct net_device *dev)
735 {
736 struct rtl8169_private *tp = netdev_priv(dev);
737--
7381.5.3.3
739
740From 81fbfc404f2a13646bee46fa98545c0023e3a67a Mon Sep 17 00:00:00 2001
741From: Francois Romieu <romieu@fr.zoreil.com>
742Date: Sat, 2 Aug 2008 21:08:49 +0200
743Subject: [PATCH] r8169: additional 8101 and 8102 support
744
745Signed-off-by: Ivan Vecera <ivecera@redhat.com>
746Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
747Cc: Edward Hsu <edward_hsu@realtek.com.tw>
748---
749 drivers/net/r8169.c | 124 ++++++++++++++++++++++++++++++++++++++++++++++++++-
750 1 files changed, 122 insertions(+), 2 deletions(-)
751
752diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
753index 52eba5c..f28c202 100644
754--- a/drivers/net/r8169.c
755+++ b/drivers/net/r8169.c
756@@ -96,6 +96,10 @@ enum mac_version {
757 RTL_GIGA_MAC_VER_04 = 0x04, // 8169SB
758 RTL_GIGA_MAC_VER_05 = 0x05, // 8110SCd
759 RTL_GIGA_MAC_VER_06 = 0x06, // 8110SCe
760+ RTL_GIGA_MAC_VER_07 = 0x07, // 8102e
761+ RTL_GIGA_MAC_VER_08 = 0x08, // 8102e
762+ RTL_GIGA_MAC_VER_09 = 0x09, // 8102e
763+ RTL_GIGA_MAC_VER_10 = 0x0a, // 8101e
764 RTL_GIGA_MAC_VER_11 = 0x0b, // 8168Bb
765 RTL_GIGA_MAC_VER_12 = 0x0c, // 8168Be
766 RTL_GIGA_MAC_VER_13 = 0x0d, // 8101Eb
767@@ -122,6 +126,10 @@ static const struct {
768 _R("RTL8169sb/8110sb", RTL_GIGA_MAC_VER_04, 0xff7e1880), // 8169SB
769 _R("RTL8169sc/8110sc", RTL_GIGA_MAC_VER_05, 0xff7e1880), // 8110SCd
770 _R("RTL8169sc/8110sc", RTL_GIGA_MAC_VER_06, 0xff7e1880), // 8110SCe
771+ _R("RTL8102e", RTL_GIGA_MAC_VER_07, 0xff7e1880), // PCI-E
772+ _R("RTL8102e", RTL_GIGA_MAC_VER_08, 0xff7e1880), // PCI-E
773+ _R("RTL8102e", RTL_GIGA_MAC_VER_09, 0xff7e1880), // PCI-E
774+ _R("RTL8101e", RTL_GIGA_MAC_VER_10, 0xff7e1880), // PCI-E
775 _R("RTL8168b/8111b", RTL_GIGA_MAC_VER_11, 0xff7e1880), // PCI-E
776 _R("RTL8168b/8111b", RTL_GIGA_MAC_VER_12, 0xff7e1880), // PCI-E
777 _R("RTL8101e", RTL_GIGA_MAC_VER_13, 0xff7e1880), // PCI-E 8139
778@@ -837,8 +845,12 @@ static int rtl8169_set_speed_xmii(struct net_device *dev,
779 }
780 }
781
782- /* The 8100e/8101e do Fast Ethernet only. */
783- if ((tp->mac_version == RTL_GIGA_MAC_VER_13) ||
784+ /* The 8100e/8101e/8102e do Fast Ethernet only. */
785+ if ((tp->mac_version == RTL_GIGA_MAC_VER_07) ||
786+ (tp->mac_version == RTL_GIGA_MAC_VER_08) ||
787+ (tp->mac_version == RTL_GIGA_MAC_VER_09) ||
788+ (tp->mac_version == RTL_GIGA_MAC_VER_10) ||
789+ (tp->mac_version == RTL_GIGA_MAC_VER_13) ||
790 (tp->mac_version == RTL_GIGA_MAC_VER_14) ||
791 (tp->mac_version == RTL_GIGA_MAC_VER_15) ||
792 (tp->mac_version == RTL_GIGA_MAC_VER_16)) {
793@@ -1212,8 +1224,17 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp,
794 { 0x7c800000, 0x30000000, RTL_GIGA_MAC_VER_11 },
795
796 /* 8101 family. */
797+ { 0x7cf00000, 0x34a00000, RTL_GIGA_MAC_VER_09 },
798+ { 0x7cf00000, 0x24a00000, RTL_GIGA_MAC_VER_09 },
799+ { 0x7cf00000, 0x34900000, RTL_GIGA_MAC_VER_08 },
800+ { 0x7cf00000, 0x24900000, RTL_GIGA_MAC_VER_08 },
801+ { 0x7cf00000, 0x34800000, RTL_GIGA_MAC_VER_07 },
802+ { 0x7cf00000, 0x24800000, RTL_GIGA_MAC_VER_07 },
803 { 0x7cf00000, 0x34000000, RTL_GIGA_MAC_VER_13 },
804+ { 0x7cf00000, 0x34300000, RTL_GIGA_MAC_VER_10 },
805 { 0x7cf00000, 0x34200000, RTL_GIGA_MAC_VER_16 },
806+ { 0x7c800000, 0x34800000, RTL_GIGA_MAC_VER_09 },
807+ { 0x7c800000, 0x24800000, RTL_GIGA_MAC_VER_09 },
808 { 0x7c800000, 0x34000000, RTL_GIGA_MAC_VER_16 },
809 /* FIXME: where did these entries come from ? -- FR */
810 { 0xfc800000, 0x38800000, RTL_GIGA_MAC_VER_15 },
811@@ -1375,6 +1396,22 @@ static void rtl8168cx_hw_phy_config(void __iomem *ioaddr)
812 rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
813 }
814
815+static void rtl8102e_hw_phy_config(void __iomem *ioaddr)
816+{
817+ struct phy_reg phy_reg_init[] = {
818+ { 0x1f, 0x0003 },
819+ { 0x08, 0x441d },
820+ { 0x01, 0x9100 },
821+ { 0x1f, 0x0000 }
822+ };
823+
824+ mdio_write(ioaddr, 0x1f, 0x0000);
825+ mdio_patch(ioaddr, 0x11, 1 << 12);
826+ mdio_patch(ioaddr, 0x19, 1 << 13);
827+
828+ rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
829+}
830+
831 static void rtl_hw_phy_config(struct net_device *dev)
832 {
833 struct rtl8169_private *tp = netdev_priv(dev);
834@@ -1392,6 +1429,11 @@ static void rtl_hw_phy_config(struct net_device *dev)
835 case RTL_GIGA_MAC_VER_04:
836 rtl8169sb_hw_phy_config(ioaddr);
837 break;
838+ case RTL_GIGA_MAC_VER_07:
839+ case RTL_GIGA_MAC_VER_08:
840+ case RTL_GIGA_MAC_VER_09:
841+ rtl8102e_hw_phy_config(ioaddr);
842+ break;
843 case RTL_GIGA_MAC_VER_18:
844 rtl8168cp_hw_phy_config(ioaddr);
845 break;
846@@ -2253,6 +2295,70 @@ static void rtl_hw_start_8168(struct net_device *dev)
847 RTL_W16(IntrMask, tp->intr_event);
848 }
849
850+#define R810X_CPCMD_QUIRK_MASK (\
851+ EnableBist | \
852+ Mac_dbgo_oe | \
853+ Force_half_dup | \
854+ Force_half_dup | \
855+ Force_txflow_en | \
856+ Cxpl_dbg_sel | \
857+ ASF | \
858+ PktCntrDisable | \
859+ PCIDAC | \
860+ PCIMulRW)
861+
862+static void rtl_hw_start_8102e_1(void __iomem *ioaddr, struct pci_dev *pdev)
863+{
864+ static struct ephy_info e_info_8102e_1[] = {
865+ { 0x01, 0, 0x6e65 },
866+ { 0x02, 0, 0x091f },
867+ { 0x03, 0, 0xc2f9 },
868+ { 0x06, 0, 0xafb5 },
869+ { 0x07, 0, 0x0e00 },
870+ { 0x19, 0, 0xec80 },
871+ { 0x01, 0, 0x2e65 },
872+ { 0x01, 0, 0x6e65 }
873+ };
874+ u8 cfg1;
875+
876+ rtl_csi_access_enable(ioaddr);
877+
878+ RTL_W8(DBG_REG, FIX_NAK_1);
879+
880+ rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
881+
882+ RTL_W8(Config1,
883+ LEDS1 | LEDS0 | Speed_down | MEMMAP | IOMAP | VPD | PMEnable);
884+ RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en);
885+
886+ cfg1 = RTL_R8(Config1);
887+ if ((cfg1 & LEDS0) && (cfg1 & LEDS1))
888+ RTL_W8(Config1, cfg1 & ~LEDS0);
889+
890+ RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R810X_CPCMD_QUIRK_MASK);
891+
892+ rtl_ephy_init(ioaddr, e_info_8102e_1, ARRAY_SIZE(e_info_8102e_1));
893+}
894+
895+static void rtl_hw_start_8102e_2(void __iomem *ioaddr, struct pci_dev *pdev)
896+{
897+ rtl_csi_access_enable(ioaddr);
898+
899+ rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
900+
901+ RTL_W8(Config1, MEMMAP | IOMAP | VPD | PMEnable);
902+ RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en);
903+
904+ RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R810X_CPCMD_QUIRK_MASK);
905+}
906+
907+static void rtl_hw_start_8102e_3(void __iomem *ioaddr, struct pci_dev *pdev)
908+{
909+ rtl_hw_start_8102e_2(ioaddr, pdev);
910+
911+ rtl_ephy_write(ioaddr, 0x03, 0xc2f9);
912+}
913+
914 static void rtl_hw_start_8101(struct net_device *dev)
915 {
916 struct rtl8169_private *tp = netdev_priv(dev);
917@@ -2269,6 +2375,20 @@ static void rtl_hw_start_8101(struct net_device *dev)
918 }
919 }
920
921+ switch (tp->mac_version) {
922+ case RTL_GIGA_MAC_VER_07:
923+ rtl_hw_start_8102e_1(ioaddr, pdev);
924+ break;
925+
926+ case RTL_GIGA_MAC_VER_08:
927+ rtl_hw_start_8102e_3(ioaddr, pdev);
928+ break;
929+
930+ case RTL_GIGA_MAC_VER_09:
931+ rtl_hw_start_8102e_2(ioaddr, pdev);
932+ break;
933+ }
934+
935 RTL_W8(Cfg9346, Cfg9346_Unlock);
936
937 RTL_W8(EarlyTxThres, EarlyTxThld);
938--
9391.5.3.3
940
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27/0042-intelfb-945gme.patch b/meta-moblin/packages/linux/linux-moblin-2.6.27/0042-intelfb-945gme.patch
new file mode 100644
index 0000000000..0f74d47bf1
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27/0042-intelfb-945gme.patch
@@ -0,0 +1,154 @@
1The following patch adds support for Intel's 945GME graphics chip to
2the intelfb driver. I have assumed that the 945GME is identical to the
3already-supported 945GM apart from its PCI IDs; this is based on a quick
4look at the X driver for these chips which seems to treat them
5identically.
6
7Signed-off-by: Phil Endecott <spam_from_intelfb@chezphil.org>
8
9---
10
11The 945GME is used in the ASUS Eee 901, and I coded this in the hope that
12I'd be able to use it to get a console at the native 1024x600 resolution
13which is not known to the BIOS. I realised too late that the intelfb
14driver does not support mode changing on laptops, so it won't be any
15use for me. But rather than throw it away I will post it here as
16essentially "untested"; maybe someone who knows more about this driver,
17and with more useful hardware to test on, can pick it up.
18
19---
20 Documentation/fb/intelfb.txt | 1 +
21 drivers/video/intelfb/intelfb.h | 7 +++++--
22 drivers/video/intelfb/intelfb_i2c.c | 1 +
23 drivers/video/intelfb/intelfbdrv.c | 7 ++++++-
24 drivers/video/intelfb/intelfbhw.c | 7 +++++++
25 5 files changed, 20 insertions(+), 3 deletions(-)
26
27Index: linux-2.6.27/Documentation/fb/intelfb.txt
28===================================================================
29--- linux-2.6.27.orig/Documentation/fb/intelfb.txt 2008-10-14 16:54:54.000000000 +0200
30+++ linux-2.6.27/Documentation/fb/intelfb.txt 2008-10-14 17:05:36.000000000 +0200
31@@ -14,6 +14,7 @@ graphics devices. These would include:
32 Intel 915GM
33 Intel 945G
34 Intel 945GM
35+ Intel 945GME
36 Intel 965G
37 Intel 965GM
38
39Index: linux-2.6.27/drivers/video/intelfb/intelfb.h
40===================================================================
41--- linux-2.6.27.orig/drivers/video/intelfb/intelfb.h 2008-10-14 16:55:37.000000000 +0200
42+++ linux-2.6.27/drivers/video/intelfb/intelfb.h 2008-10-14 17:05:36.000000000 +0200
43@@ -12,9 +12,9 @@
44 #endif
45
46 /*** Version/name ***/
47-#define INTELFB_VERSION "0.9.5"
48+#define INTELFB_VERSION "0.9.6"
49 #define INTELFB_MODULE_NAME "intelfb"
50-#define SUPPORTED_CHIPSETS "830M/845G/852GM/855GM/865G/915G/915GM/945G/945GM/965G/965GM"
51+#define SUPPORTED_CHIPSETS "830M/845G/852GM/855GM/865G/915G/915GM/945G/945GM/945GME/965G/965GM"
52
53
54 /*** Debug/feature defines ***/
55@@ -58,6 +58,7 @@
56 #define PCI_DEVICE_ID_INTEL_915GM 0x2592
57 #define PCI_DEVICE_ID_INTEL_945G 0x2772
58 #define PCI_DEVICE_ID_INTEL_945GM 0x27A2
59+#define PCI_DEVICE_ID_INTEL_945GME 0x27AE
60 #define PCI_DEVICE_ID_INTEL_965G 0x29A2
61 #define PCI_DEVICE_ID_INTEL_965GM 0x2A02
62
63@@ -160,6 +161,7 @@ enum intel_chips {
64 INTEL_915GM,
65 INTEL_945G,
66 INTEL_945GM,
67+ INTEL_945GME,
68 INTEL_965G,
69 INTEL_965GM,
70 };
71@@ -363,6 +365,7 @@ struct intelfb_info {
72 ((dinfo)->chipset == INTEL_915GM) || \
73 ((dinfo)->chipset == INTEL_945G) || \
74 ((dinfo)->chipset == INTEL_945GM) || \
75+ ((dinfo)->chipset == INTEL_945GME) || \
76 ((dinfo)->chipset == INTEL_965G) || \
77 ((dinfo)->chipset == INTEL_965GM))
78
79Index: linux-2.6.27/drivers/video/intelfb/intelfb_i2c.c
80===================================================================
81--- linux-2.6.27.orig/drivers/video/intelfb/intelfb_i2c.c 2008-10-14 16:55:37.000000000 +0200
82+++ linux-2.6.27/drivers/video/intelfb/intelfb_i2c.c 2008-10-14 17:05:36.000000000 +0200
83@@ -171,6 +171,7 @@ void intelfb_create_i2c_busses(struct in
84 /* has some LVDS + tv-out */
85 case INTEL_945G:
86 case INTEL_945GM:
87+ case INTEL_945GME:
88 case INTEL_965G:
89 case INTEL_965GM:
90 /* SDVO ports have a single control bus - 2 devices */
91Index: linux-2.6.27/drivers/video/intelfb/intelfbdrv.c
92===================================================================
93--- linux-2.6.27.orig/drivers/video/intelfb/intelfbdrv.c 2008-10-14 16:55:37.000000000 +0200
94+++ linux-2.6.27/drivers/video/intelfb/intelfbdrv.c 2008-10-14 17:05:36.000000000 +0200
95@@ -2,7 +2,7 @@
96 * intelfb
97 *
98 * Linux framebuffer driver for Intel(R) 830M/845G/852GM/855GM/865G/915G/915GM/
99- * 945G/945GM/965G/965GM integrated graphics chips.
100+ * 945G/945GM/945GME/965G/965GM integrated graphics chips.
101 *
102 * Copyright © 2002, 2003 David Dawes <dawes@xfree86.org>
103 * 2004 Sylvain Meyer
104@@ -102,6 +102,9 @@
105 *
106 * 04/2008 - Version 0.9.5
107 * Add support for 965G/965GM. (Maik Broemme <mbroemme@plusserver.de>)
108+ *
109+ * 08/2008 - Version 0.9.6
110+ * Add support for 945GME. (Phil Endecott <spam_from_intelfb@chezphil.org>)
111 */
112
113 #include <linux/module.h>
114@@ -183,6 +186,7 @@ static struct pci_device_id intelfb_pci_
115 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_915GM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_915GM },
116 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_945G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_945G },
117 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_945GM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_945GM },
118+ { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_945GME, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_945GME },
119 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_965G, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_965G },
120 { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_965GM, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, INTELFB_CLASS_MASK, INTEL_965GM },
121 { 0, }
122@@ -555,6 +559,7 @@ static int __devinit intelfb_pci_registe
123 (ent->device == PCI_DEVICE_ID_INTEL_915GM) ||
124 (ent->device == PCI_DEVICE_ID_INTEL_945G) ||
125 (ent->device == PCI_DEVICE_ID_INTEL_945GM) ||
126+ (ent->device == PCI_DEVICE_ID_INTEL_945GME) ||
127 (ent->device == PCI_DEVICE_ID_INTEL_965G) ||
128 (ent->device == PCI_DEVICE_ID_INTEL_965GM)) {
129
130Index: linux-2.6.27/drivers/video/intelfb/intelfbhw.c
131===================================================================
132--- linux-2.6.27.orig/drivers/video/intelfb/intelfbhw.c 2008-10-14 16:55:37.000000000 +0200
133+++ linux-2.6.27/drivers/video/intelfb/intelfbhw.c 2008-10-14 17:05:36.000000000 +0200
134@@ -143,6 +143,12 @@ int intelfbhw_get_chipset(struct pci_dev
135 dinfo->mobile = 1;
136 dinfo->pll_index = PLLS_I9xx;
137 return 0;
138+ case PCI_DEVICE_ID_INTEL_945GME:
139+ dinfo->name = "Intel(R) 945GME";
140+ dinfo->chipset = INTEL_945GME;
141+ dinfo->mobile = 1;
142+ dinfo->pll_index = PLLS_I9xx;
143+ return 0;
144 case PCI_DEVICE_ID_INTEL_965G:
145 dinfo->name = "Intel(R) 965G";
146 dinfo->chipset = INTEL_965G;
147@@ -186,6 +192,7 @@ int intelfbhw_get_memory(struct pci_dev
148 case PCI_DEVICE_ID_INTEL_915GM:
149 case PCI_DEVICE_ID_INTEL_945G:
150 case PCI_DEVICE_ID_INTEL_945GM:
151+ case PCI_DEVICE_ID_INTEL_945GME:
152 case PCI_DEVICE_ID_INTEL_965G:
153 case PCI_DEVICE_ID_INTEL_965GM:
154 /* 915, 945 and 965 chipsets support a 256MB aperture.
diff --git a/meta-moblin/packages/linux/linux-moblin-2.6.27/defconfig-netbook b/meta-moblin/packages/linux/linux-moblin-2.6.27/defconfig-netbook
new file mode 100644
index 0000000000..e5b7cf369f
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin-2.6.27/defconfig-netbook
@@ -0,0 +1,2406 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.27
4# Tue Oct 14 17:07:32 2008
5#
6# CONFIG_64BIT is not set
7CONFIG_X86_32=y
8# CONFIG_X86_64 is not set
9CONFIG_X86=y
10CONFIG_ARCH_DEFCONFIG="arch/x86/configs/i386_defconfig"
11# CONFIG_GENERIC_LOCKBREAK is not set
12CONFIG_GENERIC_TIME=y
13CONFIG_GENERIC_CMOS_UPDATE=y
14CONFIG_CLOCKSOURCE_WATCHDOG=y
15CONFIG_GENERIC_CLOCKEVENTS=y
16CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
17CONFIG_LOCKDEP_SUPPORT=y
18CONFIG_STACKTRACE_SUPPORT=y
19CONFIG_HAVE_LATENCYTOP_SUPPORT=y
20CONFIG_FAST_CMPXCHG_LOCAL=y
21CONFIG_MMU=y
22CONFIG_ZONE_DMA=y
23CONFIG_GENERIC_ISA_DMA=y
24CONFIG_GENERIC_IOMAP=y
25CONFIG_GENERIC_BUG=y
26CONFIG_GENERIC_HWEIGHT=y
27# CONFIG_GENERIC_GPIO is not set
28CONFIG_ARCH_MAY_HAVE_PC_FDC=y
29# CONFIG_RWSEM_GENERIC_SPINLOCK is not set
30CONFIG_RWSEM_XCHGADD_ALGORITHM=y
31# CONFIG_ARCH_HAS_ILOG2_U32 is not set
32# CONFIG_ARCH_HAS_ILOG2_U64 is not set
33CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
34CONFIG_GENERIC_CALIBRATE_DELAY=y
35# CONFIG_GENERIC_TIME_VSYSCALL is not set
36CONFIG_ARCH_HAS_CPU_RELAX=y
37CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y
38CONFIG_HAVE_SETUP_PER_CPU_AREA=y
39# CONFIG_HAVE_CPUMASK_OF_CPU_MAP is not set
40CONFIG_ARCH_HIBERNATION_POSSIBLE=y
41CONFIG_ARCH_SUSPEND_POSSIBLE=y
42# CONFIG_ZONE_DMA32 is not set
43CONFIG_ARCH_POPULATES_NODE_MAP=y
44# CONFIG_AUDIT_ARCH is not set
45CONFIG_ARCH_SUPPORTS_AOUT=y
46CONFIG_ARCH_SUPPORTS_OPTIMIZED_INLINING=y
47CONFIG_GENERIC_HARDIRQS=y
48CONFIG_GENERIC_IRQ_PROBE=y
49CONFIG_GENERIC_PENDING_IRQ=y
50CONFIG_X86_SMP=y
51CONFIG_X86_32_SMP=y
52CONFIG_X86_HT=y
53CONFIG_X86_BIOS_REBOOT=y
54CONFIG_X86_TRAMPOLINE=y
55CONFIG_KTIME_SCALAR=y
56CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
57
58#
59# General setup
60#
61CONFIG_EXPERIMENTAL=y
62CONFIG_LOCK_KERNEL=y
63CONFIG_INIT_ENV_ARG_LIMIT=32
64CONFIG_LOCALVERSION="-netbook"
65# CONFIG_LOCALVERSION_AUTO is not set
66CONFIG_SWAP=y
67CONFIG_SYSVIPC=y
68CONFIG_SYSVIPC_SYSCTL=y
69CONFIG_POSIX_MQUEUE=y
70CONFIG_BSD_PROCESS_ACCT=y
71CONFIG_BSD_PROCESS_ACCT_V3=y
72CONFIG_TASKSTATS=y
73CONFIG_TASK_DELAY_ACCT=y
74CONFIG_TASK_XACCT=y
75CONFIG_TASK_IO_ACCOUNTING=y
76CONFIG_AUDIT=y
77CONFIG_AUDITSYSCALL=y
78CONFIG_AUDIT_TREE=y
79CONFIG_IKCONFIG=y
80CONFIG_IKCONFIG_PROC=y
81CONFIG_LOG_BUF_SHIFT=17
82# CONFIG_CGROUPS is not set
83CONFIG_HAVE_UNSTABLE_SCHED_CLOCK=y
84# CONFIG_GROUP_SCHED is not set
85# CONFIG_SYSFS_DEPRECATED_V2 is not set
86CONFIG_RELAY=y
87CONFIG_NAMESPACES=y
88# CONFIG_UTS_NS is not set
89# CONFIG_IPC_NS is not set
90CONFIG_USER_NS=y
91# CONFIG_PID_NS is not set
92CONFIG_BLK_DEV_INITRD=y
93CONFIG_INITRAMFS_SOURCE=""
94CONFIG_CC_OPTIMIZE_FOR_SIZE=y
95CONFIG_FASTBOOT=y
96CONFIG_SYSCTL=y
97# CONFIG_EMBEDDED is not set
98CONFIG_UID16=y
99CONFIG_SYSCTL_SYSCALL=y
100CONFIG_KALLSYMS=y
101CONFIG_KALLSYMS_ALL=y
102CONFIG_KALLSYMS_EXTRA_PASS=y
103CONFIG_HOTPLUG=y
104CONFIG_PRINTK=y
105CONFIG_BUG=y
106CONFIG_ELF_CORE=y
107CONFIG_PCSPKR_PLATFORM=y
108# CONFIG_COMPAT_BRK is not set
109CONFIG_BASE_FULL=y
110CONFIG_FUTEX=y
111CONFIG_ANON_INODES=y
112CONFIG_EPOLL=y
113CONFIG_SIGNALFD=y
114CONFIG_TIMERFD=y
115CONFIG_EVENTFD=y
116CONFIG_SHMEM=y
117CONFIG_VM_EVENT_COUNTERS=y
118CONFIG_SLAB=y
119# CONFIG_SLUB is not set
120# CONFIG_SLOB is not set
121CONFIG_PROFILING=y
122# CONFIG_MARKERS is not set
123# CONFIG_OPROFILE is not set
124CONFIG_HAVE_OPROFILE=y
125# CONFIG_KPROBES is not set
126CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
127CONFIG_HAVE_IOREMAP_PROT=y
128CONFIG_HAVE_KPROBES=y
129CONFIG_HAVE_KRETPROBES=y
130# CONFIG_HAVE_ARCH_TRACEHOOK is not set
131# CONFIG_HAVE_DMA_ATTRS is not set
132CONFIG_USE_GENERIC_SMP_HELPERS=y
133# CONFIG_HAVE_CLK is not set
134CONFIG_PROC_PAGE_MONITOR=y
135CONFIG_HAVE_GENERIC_DMA_COHERENT=y
136CONFIG_SLABINFO=y
137CONFIG_RT_MUTEXES=y
138# CONFIG_TINY_SHMEM is not set
139CONFIG_BASE_SMALL=0
140CONFIG_MODULES=y
141# CONFIG_MODULE_FORCE_LOAD is not set
142CONFIG_MODULE_UNLOAD=y
143# CONFIG_MODULE_FORCE_UNLOAD is not set
144# CONFIG_MODVERSIONS is not set
145# CONFIG_MODULE_SRCVERSION_ALL is not set
146CONFIG_KMOD=y
147CONFIG_STOP_MACHINE=y
148CONFIG_BLOCK=y
149# CONFIG_LBD is not set
150CONFIG_BLK_DEV_IO_TRACE=y
151# CONFIG_LSF is not set
152CONFIG_BLK_DEV_BSG=y
153# CONFIG_BLK_DEV_INTEGRITY is not set
154
155#
156# IO Schedulers
157#
158CONFIG_IOSCHED_NOOP=y
159# CONFIG_IOSCHED_AS is not set
160# CONFIG_IOSCHED_DEADLINE is not set
161CONFIG_IOSCHED_CFQ=y
162# CONFIG_DEFAULT_AS is not set
163# CONFIG_DEFAULT_DEADLINE is not set
164CONFIG_DEFAULT_CFQ=y
165# CONFIG_DEFAULT_NOOP is not set
166CONFIG_DEFAULT_IOSCHED="cfq"
167CONFIG_CLASSIC_RCU=y
168
169#
170# Processor type and features
171#
172CONFIG_TICK_ONESHOT=y
173CONFIG_NO_HZ=y
174CONFIG_HIGH_RES_TIMERS=y
175CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
176CONFIG_SMP=y
177CONFIG_X86_FIND_SMP_CONFIG=y
178CONFIG_X86_MPPARSE=y
179CONFIG_X86_PC=y
180# CONFIG_X86_ELAN is not set
181# CONFIG_X86_VOYAGER is not set
182# CONFIG_X86_GENERICARCH is not set
183# CONFIG_X86_VSMP is not set
184# CONFIG_X86_RDC321X is not set
185CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
186# CONFIG_PARAVIRT_GUEST is not set
187# CONFIG_MEMTEST is not set
188# CONFIG_M386 is not set
189# CONFIG_M486 is not set
190# CONFIG_M586 is not set
191# CONFIG_M586TSC is not set
192# CONFIG_M586MMX is not set
193CONFIG_M686=y
194# CONFIG_MPENTIUMII is not set
195# CONFIG_MPENTIUMIII is not set
196# CONFIG_MPENTIUMM is not set
197# CONFIG_MPENTIUM4 is not set
198# CONFIG_MK6 is not set
199# CONFIG_MK7 is not set
200# CONFIG_MK8 is not set
201# CONFIG_MCRUSOE is not set
202# CONFIG_MEFFICEON is not set
203# CONFIG_MWINCHIPC6 is not set
204# CONFIG_MWINCHIP2 is not set
205# CONFIG_MWINCHIP3D is not set
206# CONFIG_MGEODEGX1 is not set
207# CONFIG_MGEODE_LX is not set
208# CONFIG_MCYRIXIII is not set
209# CONFIG_MVIAC3_2 is not set
210# CONFIG_MVIAC7 is not set
211# CONFIG_MPSC is not set
212# CONFIG_MCORE2 is not set
213# CONFIG_GENERIC_CPU is not set
214# CONFIG_X86_GENERIC is not set
215CONFIG_X86_CPU=y
216CONFIG_X86_CMPXCHG=y
217CONFIG_X86_L1_CACHE_SHIFT=5
218CONFIG_X86_XADD=y
219# CONFIG_X86_PPRO_FENCE is not set
220CONFIG_X86_WP_WORKS_OK=y
221CONFIG_X86_INVLPG=y
222CONFIG_X86_BSWAP=y
223CONFIG_X86_POPAD_OK=y
224CONFIG_X86_USE_PPRO_CHECKSUM=y
225CONFIG_X86_TSC=y
226CONFIG_X86_CMOV=y
227CONFIG_X86_MINIMUM_CPU_FAMILY=4
228CONFIG_X86_DEBUGCTLMSR=y
229CONFIG_HPET_TIMER=y
230CONFIG_HPET_EMULATE_RTC=y
231CONFIG_DMI=y
232# CONFIG_IOMMU_HELPER is not set
233CONFIG_NR_CPUS=2
234CONFIG_SCHED_SMT=y
235CONFIG_SCHED_MC=y
236# CONFIG_PREEMPT_NONE is not set
237CONFIG_PREEMPT_VOLUNTARY=y
238# CONFIG_PREEMPT is not set
239CONFIG_X86_LOCAL_APIC=y
240CONFIG_X86_IO_APIC=y
241CONFIG_X86_MCE=y
242# CONFIG_X86_MCE_NONFATAL is not set
243# CONFIG_X86_MCE_P4THERMAL is not set
244CONFIG_VM86=y
245# CONFIG_TOSHIBA is not set
246# CONFIG_I8K is not set
247# CONFIG_X86_REBOOTFIXUPS is not set
248CONFIG_MICROCODE=y
249CONFIG_MICROCODE_OLD_INTERFACE=y
250CONFIG_X86_MSR=y
251CONFIG_X86_CPUID=y
252# CONFIG_NOHIGHMEM is not set
253CONFIG_HIGHMEM4G=y
254# CONFIG_HIGHMEM64G is not set
255CONFIG_PAGE_OFFSET=0xC0000000
256CONFIG_HIGHMEM=y
257CONFIG_NEED_NODE_MEMMAP_SIZE=y
258CONFIG_ARCH_FLATMEM_ENABLE=y
259CONFIG_ARCH_SPARSEMEM_ENABLE=y
260CONFIG_ARCH_SELECT_MEMORY_MODEL=y
261CONFIG_SELECT_MEMORY_MODEL=y
262# CONFIG_FLATMEM_MANUAL is not set
263# CONFIG_DISCONTIGMEM_MANUAL is not set
264CONFIG_SPARSEMEM_MANUAL=y
265CONFIG_SPARSEMEM=y
266CONFIG_HAVE_MEMORY_PRESENT=y
267CONFIG_SPARSEMEM_STATIC=y
268# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
269
270#
271# Memory hotplug is currently incompatible with Software Suspend
272#
273CONFIG_PAGEFLAGS_EXTENDED=y
274CONFIG_SPLIT_PTLOCK_CPUS=4
275CONFIG_RESOURCES_64BIT=y
276CONFIG_ZONE_DMA_FLAG=1
277CONFIG_BOUNCE=y
278CONFIG_VIRT_TO_BUS=y
279# CONFIG_HIGHPTE is not set
280# CONFIG_MATH_EMULATION is not set
281CONFIG_MTRR=y
282# CONFIG_MTRR_SANITIZER is not set
283# CONFIG_X86_PAT is not set
284# CONFIG_EFI is not set
285# CONFIG_IRQBALANCE is not set
286# CONFIG_SECCOMP is not set
287# CONFIG_HZ_100 is not set
288# CONFIG_HZ_250 is not set
289# CONFIG_HZ_300 is not set
290CONFIG_HZ_1000=y
291CONFIG_HZ=1000
292CONFIG_SCHED_HRTICK=y
293CONFIG_KEXEC=y
294CONFIG_CRASH_DUMP=y
295# CONFIG_KEXEC_JUMP is not set
296CONFIG_PHYSICAL_START=0x400000
297CONFIG_RELOCATABLE=y
298CONFIG_PHYSICAL_ALIGN=0x200000
299CONFIG_HOTPLUG_CPU=y
300CONFIG_COMPAT_VDSO=y
301CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
302
303#
304# Power management options
305#
306CONFIG_PM=y
307CONFIG_PM_DEBUG=y
308# CONFIG_PM_VERBOSE is not set
309CONFIG_CAN_PM_TRACE=y
310CONFIG_PM_TRACE=y
311CONFIG_PM_TRACE_RTC=y
312CONFIG_PM_SLEEP_SMP=y
313CONFIG_PM_SLEEP=y
314CONFIG_SUSPEND=y
315# CONFIG_PM_TEST_SUSPEND is not set
316CONFIG_SUSPEND_FREEZER=y
317CONFIG_HIBERNATION=y
318CONFIG_PM_STD_PARTITION=""
319CONFIG_ACPI=y
320CONFIG_ACPI_SLEEP=y
321CONFIG_ACPI_PROCFS=y
322CONFIG_ACPI_PROCFS_POWER=y
323CONFIG_ACPI_SYSFS_POWER=y
324CONFIG_ACPI_PROC_EVENT=y
325CONFIG_ACPI_AC=y
326CONFIG_ACPI_BATTERY=m
327CONFIG_ACPI_BUTTON=y
328CONFIG_ACPI_VIDEO=y
329CONFIG_ACPI_FAN=y
330CONFIG_ACPI_DOCK=y
331# CONFIG_ACPI_BAY is not set
332CONFIG_ACPI_PROCESSOR=y
333CONFIG_ACPI_HOTPLUG_CPU=y
334CONFIG_ACPI_THERMAL=y
335CONFIG_ACPI_WMI=m
336CONFIG_ACPI_ASUS=y
337# CONFIG_ACPI_TOSHIBA is not set
338# CONFIG_ACPI_CUSTOM_DSDT is not set
339CONFIG_ACPI_BLACKLIST_YEAR=0
340# CONFIG_ACPI_DEBUG is not set
341CONFIG_ACPI_EC=y
342# CONFIG_ACPI_PCI_SLOT is not set
343CONFIG_ACPI_POWER=y
344CONFIG_ACPI_SYSTEM=y
345CONFIG_X86_PM_TIMER=y
346CONFIG_ACPI_CONTAINER=y
347CONFIG_ACPI_SBS=m
348# CONFIG_APM is not set
349
350#
351# CPU Frequency scaling
352#
353CONFIG_CPU_FREQ=y
354CONFIG_CPU_FREQ_TABLE=y
355CONFIG_CPU_FREQ_DEBUG=y
356CONFIG_CPU_FREQ_STAT=m
357CONFIG_CPU_FREQ_STAT_DETAILS=y
358CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
359# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
360# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
361# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
362# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
363CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
364# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
365CONFIG_CPU_FREQ_GOV_USERSPACE=y
366CONFIG_CPU_FREQ_GOV_ONDEMAND=y
367# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
368
369#
370# CPUFreq processor drivers
371#
372CONFIG_X86_ACPI_CPUFREQ=y
373# CONFIG_X86_POWERNOW_K6 is not set
374# CONFIG_X86_POWERNOW_K7 is not set
375# CONFIG_X86_POWERNOW_K8 is not set
376# CONFIG_X86_GX_SUSPMOD is not set
377# CONFIG_X86_SPEEDSTEP_CENTRINO is not set
378# CONFIG_X86_SPEEDSTEP_ICH is not set
379# CONFIG_X86_SPEEDSTEP_SMI is not set
380# CONFIG_X86_P4_CLOCKMOD is not set
381# CONFIG_X86_CPUFREQ_NFORCE2 is not set
382# CONFIG_X86_LONGRUN is not set
383# CONFIG_X86_LONGHAUL is not set
384# CONFIG_X86_E_POWERSAVER is not set
385
386#
387# shared options
388#
389# CONFIG_X86_ACPI_CPUFREQ_PROC_INTF is not set
390# CONFIG_X86_SPEEDSTEP_LIB is not set
391CONFIG_CPU_IDLE=y
392CONFIG_CPU_IDLE_GOV_LADDER=y
393CONFIG_CPU_IDLE_GOV_MENU=y
394
395#
396# Bus options (PCI etc.)
397#
398CONFIG_PCI=y
399# CONFIG_PCI_GOBIOS is not set
400# CONFIG_PCI_GOMMCONFIG is not set
401# CONFIG_PCI_GODIRECT is not set
402# CONFIG_PCI_GOOLPC is not set
403CONFIG_PCI_GOANY=y
404CONFIG_PCI_BIOS=y
405CONFIG_PCI_DIRECT=y
406CONFIG_PCI_MMCONFIG=y
407CONFIG_PCI_DOMAINS=y
408CONFIG_PCIEPORTBUS=y
409CONFIG_PCIEAER=y
410CONFIG_PCIEASPM=y
411# CONFIG_PCIEASPM_DEBUG is not set
412CONFIG_ARCH_SUPPORTS_MSI=y
413CONFIG_PCI_MSI=y
414CONFIG_PCI_LEGACY=y
415# CONFIG_PCI_DEBUG is not set
416CONFIG_HT_IRQ=y
417CONFIG_ISA_DMA_API=y
418# CONFIG_ISA is not set
419# CONFIG_MCA is not set
420# CONFIG_SCx200 is not set
421# CONFIG_OLPC is not set
422CONFIG_K8_NB=y
423# CONFIG_PCCARD is not set
424# CONFIG_HOTPLUG_PCI is not set
425
426#
427# Executable file formats / Emulations
428#
429CONFIG_BINFMT_ELF=y
430# CONFIG_BINFMT_AOUT is not set
431CONFIG_BINFMT_MISC=y
432CONFIG_NET=y
433
434#
435# Networking options
436#
437CONFIG_PACKET=y
438CONFIG_PACKET_MMAP=y
439CONFIG_UNIX=y
440CONFIG_XFRM=y
441CONFIG_XFRM_USER=y
442CONFIG_XFRM_SUB_POLICY=y
443CONFIG_XFRM_MIGRATE=y
444CONFIG_XFRM_STATISTICS=y
445CONFIG_XFRM_IPCOMP=m
446CONFIG_NET_KEY=m
447CONFIG_NET_KEY_MIGRATE=y
448CONFIG_INET=y
449CONFIG_IP_MULTICAST=y
450# CONFIG_IP_ADVANCED_ROUTER is not set
451CONFIG_IP_FIB_HASH=y
452# CONFIG_IP_PNP is not set
453# CONFIG_NET_IPIP is not set
454# CONFIG_NET_IPGRE is not set
455CONFIG_IP_MROUTE=y
456CONFIG_IP_PIMSM_V1=y
457CONFIG_IP_PIMSM_V2=y
458# CONFIG_ARPD is not set
459CONFIG_SYN_COOKIES=y
460CONFIG_INET_AH=m
461CONFIG_INET_ESP=m
462CONFIG_INET_IPCOMP=m
463CONFIG_INET_XFRM_TUNNEL=m
464CONFIG_INET_TUNNEL=m
465CONFIG_INET_XFRM_MODE_TRANSPORT=m
466CONFIG_INET_XFRM_MODE_TUNNEL=m
467CONFIG_INET_XFRM_MODE_BEET=m
468CONFIG_INET_LRO=y
469CONFIG_INET_DIAG=m
470CONFIG_INET_TCP_DIAG=m
471CONFIG_TCP_CONG_ADVANCED=y
472CONFIG_TCP_CONG_BIC=m
473CONFIG_TCP_CONG_CUBIC=y
474# CONFIG_TCP_CONG_WESTWOOD is not set
475# CONFIG_TCP_CONG_HTCP is not set
476# CONFIG_TCP_CONG_HSTCP is not set
477# CONFIG_TCP_CONG_HYBLA is not set
478# CONFIG_TCP_CONG_VEGAS is not set
479# CONFIG_TCP_CONG_SCALABLE is not set
480# CONFIG_TCP_CONG_LP is not set
481# CONFIG_TCP_CONG_VENO is not set
482# CONFIG_TCP_CONG_YEAH is not set
483# CONFIG_TCP_CONG_ILLINOIS is not set
484# CONFIG_DEFAULT_BIC is not set
485CONFIG_DEFAULT_CUBIC=y
486# CONFIG_DEFAULT_HTCP is not set
487# CONFIG_DEFAULT_VEGAS is not set
488# CONFIG_DEFAULT_WESTWOOD is not set
489# CONFIG_DEFAULT_RENO is not set
490CONFIG_DEFAULT_TCP_CONG="cubic"
491CONFIG_TCP_MD5SIG=y
492# CONFIG_IP_VS is not set
493CONFIG_IPV6=y
494CONFIG_IPV6_PRIVACY=y
495CONFIG_IPV6_ROUTER_PREF=y
496CONFIG_IPV6_ROUTE_INFO=y
497CONFIG_IPV6_OPTIMISTIC_DAD=y
498CONFIG_INET6_AH=m
499CONFIG_INET6_ESP=m
500CONFIG_INET6_IPCOMP=m
501CONFIG_IPV6_MIP6=m
502CONFIG_INET6_XFRM_TUNNEL=m
503CONFIG_INET6_TUNNEL=m
504CONFIG_INET6_XFRM_MODE_TRANSPORT=m
505CONFIG_INET6_XFRM_MODE_TUNNEL=m
506CONFIG_INET6_XFRM_MODE_BEET=m
507CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
508CONFIG_IPV6_SIT=m
509CONFIG_IPV6_NDISC_NODETYPE=y
510CONFIG_IPV6_TUNNEL=m
511CONFIG_IPV6_MULTIPLE_TABLES=y
512CONFIG_IPV6_SUBTREES=y
513# CONFIG_IPV6_MROUTE is not set
514CONFIG_NETLABEL=y
515CONFIG_NETWORK_SECMARK=y
516CONFIG_NETFILTER=y
517# CONFIG_NETFILTER_DEBUG is not set
518CONFIG_NETFILTER_ADVANCED=y
519
520#
521# Core Netfilter Configuration
522#
523CONFIG_NETFILTER_NETLINK=m
524CONFIG_NETFILTER_NETLINK_QUEUE=m
525CONFIG_NETFILTER_NETLINK_LOG=m
526CONFIG_NF_CONNTRACK=y
527CONFIG_NF_CT_ACCT=y
528CONFIG_NF_CONNTRACK_MARK=y
529CONFIG_NF_CONNTRACK_SECMARK=y
530CONFIG_NF_CONNTRACK_EVENTS=y
531# CONFIG_NF_CT_PROTO_DCCP is not set
532CONFIG_NF_CT_PROTO_GRE=m
533CONFIG_NF_CT_PROTO_SCTP=m
534CONFIG_NF_CT_PROTO_UDPLITE=m
535CONFIG_NF_CONNTRACK_AMANDA=m
536CONFIG_NF_CONNTRACK_FTP=m
537CONFIG_NF_CONNTRACK_H323=m
538CONFIG_NF_CONNTRACK_IRC=m
539CONFIG_NF_CONNTRACK_NETBIOS_NS=m
540CONFIG_NF_CONNTRACK_PPTP=m
541CONFIG_NF_CONNTRACK_SANE=m
542CONFIG_NF_CONNTRACK_SIP=m
543CONFIG_NF_CONNTRACK_TFTP=m
544CONFIG_NF_CT_NETLINK=m
545CONFIG_NETFILTER_XTABLES=y
546CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
547CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
548CONFIG_NETFILTER_XT_TARGET_DSCP=m
549CONFIG_NETFILTER_XT_TARGET_MARK=m
550CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
551CONFIG_NETFILTER_XT_TARGET_NFLOG=m
552CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
553CONFIG_NETFILTER_XT_TARGET_RATEEST=m
554CONFIG_NETFILTER_XT_TARGET_TRACE=m
555CONFIG_NETFILTER_XT_TARGET_SECMARK=m
556CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
557CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
558CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP=m
559CONFIG_NETFILTER_XT_MATCH_COMMENT=m
560CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
561CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
562CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
563CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
564# CONFIG_NETFILTER_XT_MATCH_DCCP is not set
565CONFIG_NETFILTER_XT_MATCH_DSCP=m
566CONFIG_NETFILTER_XT_MATCH_ESP=m
567CONFIG_NETFILTER_XT_MATCH_HELPER=m
568CONFIG_NETFILTER_XT_MATCH_IPRANGE=m
569CONFIG_NETFILTER_XT_MATCH_LENGTH=m
570CONFIG_NETFILTER_XT_MATCH_LIMIT=m
571CONFIG_NETFILTER_XT_MATCH_MAC=m
572CONFIG_NETFILTER_XT_MATCH_MARK=m
573CONFIG_NETFILTER_XT_MATCH_OWNER=m
574CONFIG_NETFILTER_XT_MATCH_POLICY=m
575CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
576CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
577CONFIG_NETFILTER_XT_MATCH_QUOTA=m
578CONFIG_NETFILTER_XT_MATCH_RATEEST=m
579CONFIG_NETFILTER_XT_MATCH_REALM=m
580CONFIG_NETFILTER_XT_MATCH_SCTP=m
581CONFIG_NETFILTER_XT_MATCH_STATE=y
582CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
583CONFIG_NETFILTER_XT_MATCH_STRING=m
584CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
585CONFIG_NETFILTER_XT_MATCH_TIME=m
586CONFIG_NETFILTER_XT_MATCH_U32=m
587CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
588
589#
590# IP: Netfilter Configuration
591#
592CONFIG_NF_CONNTRACK_IPV4=y
593# CONFIG_NF_CONNTRACK_PROC_COMPAT is not set
594CONFIG_IP_NF_QUEUE=m
595CONFIG_IP_NF_IPTABLES=y
596CONFIG_IP_NF_MATCH_RECENT=m
597CONFIG_IP_NF_MATCH_ECN=m
598CONFIG_IP_NF_MATCH_AH=m
599CONFIG_IP_NF_MATCH_TTL=m
600CONFIG_IP_NF_MATCH_ADDRTYPE=m
601CONFIG_IP_NF_FILTER=y
602CONFIG_IP_NF_TARGET_REJECT=y
603CONFIG_IP_NF_TARGET_LOG=m
604CONFIG_IP_NF_TARGET_ULOG=m
605CONFIG_NF_NAT=m
606CONFIG_NF_NAT_NEEDED=y
607CONFIG_IP_NF_TARGET_MASQUERADE=m
608CONFIG_IP_NF_TARGET_REDIRECT=m
609CONFIG_IP_NF_TARGET_NETMAP=m
610CONFIG_NF_NAT_SNMP_BASIC=m
611CONFIG_NF_NAT_PROTO_GRE=m
612CONFIG_NF_NAT_PROTO_UDPLITE=m
613CONFIG_NF_NAT_PROTO_SCTP=m
614CONFIG_NF_NAT_FTP=m
615CONFIG_NF_NAT_IRC=m
616CONFIG_NF_NAT_TFTP=m
617CONFIG_NF_NAT_AMANDA=m
618CONFIG_NF_NAT_PPTP=m
619CONFIG_NF_NAT_H323=m
620CONFIG_NF_NAT_SIP=m
621CONFIG_IP_NF_MANGLE=m
622CONFIG_IP_NF_TARGET_ECN=m
623CONFIG_IP_NF_TARGET_TTL=m
624CONFIG_IP_NF_TARGET_CLUSTERIP=m
625CONFIG_IP_NF_RAW=m
626# CONFIG_IP_NF_SECURITY is not set
627CONFIG_IP_NF_ARPTABLES=m
628CONFIG_IP_NF_ARPFILTER=m
629CONFIG_IP_NF_ARP_MANGLE=m
630
631#
632# IPv6: Netfilter Configuration
633#
634CONFIG_NF_CONNTRACK_IPV6=y
635CONFIG_IP6_NF_QUEUE=m
636CONFIG_IP6_NF_IPTABLES=y
637CONFIG_IP6_NF_MATCH_RT=m
638CONFIG_IP6_NF_MATCH_OPTS=m
639CONFIG_IP6_NF_MATCH_FRAG=m
640CONFIG_IP6_NF_MATCH_HL=m
641CONFIG_IP6_NF_MATCH_IPV6HEADER=m
642CONFIG_IP6_NF_MATCH_AH=m
643CONFIG_IP6_NF_MATCH_MH=m
644CONFIG_IP6_NF_MATCH_EUI64=m
645CONFIG_IP6_NF_FILTER=y
646CONFIG_IP6_NF_TARGET_LOG=m
647CONFIG_IP6_NF_TARGET_REJECT=y
648CONFIG_IP6_NF_MANGLE=m
649CONFIG_IP6_NF_TARGET_HL=m
650CONFIG_IP6_NF_RAW=m
651# CONFIG_IP6_NF_SECURITY is not set
652# CONFIG_IP_DCCP is not set
653# CONFIG_IP_SCTP is not set
654# CONFIG_TIPC is not set
655# CONFIG_ATM is not set
656# CONFIG_BRIDGE is not set
657# CONFIG_VLAN_8021Q is not set
658# CONFIG_DECNET is not set
659# CONFIG_LLC2 is not set
660# CONFIG_IPX is not set
661# CONFIG_ATALK is not set
662# CONFIG_X25 is not set
663# CONFIG_LAPB is not set
664# CONFIG_ECONET is not set
665# CONFIG_WAN_ROUTER is not set
666# CONFIG_NET_SCHED is not set
667CONFIG_NET_CLS_ROUTE=y
668
669#
670# Network testing
671#
672# CONFIG_NET_PKTGEN is not set
673# CONFIG_HAMRADIO is not set
674# CONFIG_CAN is not set
675# CONFIG_IRDA is not set
676CONFIG_BT=m
677CONFIG_BT_L2CAP=m
678CONFIG_BT_SCO=m
679CONFIG_BT_RFCOMM=m
680CONFIG_BT_RFCOMM_TTY=y
681CONFIG_BT_BNEP=m
682# CONFIG_BT_BNEP_MC_FILTER is not set
683# CONFIG_BT_BNEP_PROTO_FILTER is not set
684# CONFIG_BT_HIDP is not set
685
686#
687# Bluetooth device drivers
688#
689CONFIG_BT_HCIUSB=m
690CONFIG_BT_HCIUSB_SCO=y
691# CONFIG_BT_HCIBTUSB is not set
692CONFIG_BT_HCIBTSDIO=m
693CONFIG_BT_HCIUART=m
694CONFIG_BT_HCIUART_H4=y
695CONFIG_BT_HCIUART_BCSP=y
696CONFIG_BT_HCIUART_LL=y
697CONFIG_BT_HCIBCM203X=m
698CONFIG_BT_HCIBPA10X=m
699CONFIG_BT_HCIBFUSB=m
700CONFIG_BT_HCIVHCI=m
701# CONFIG_AF_RXRPC is not set
702CONFIG_FIB_RULES=y
703
704#
705# Wireless
706#
707CONFIG_CFG80211=m
708CONFIG_NL80211=y
709CONFIG_WIRELESS_EXT=y
710# CONFIG_WIRELESS_EXT_SYSFS is not set
711CONFIG_MAC80211=m
712
713#
714# Rate control algorithm selection
715#
716CONFIG_MAC80211_RC_PID=y
717CONFIG_MAC80211_RC_DEFAULT_PID=y
718CONFIG_MAC80211_RC_DEFAULT="pid"
719CONFIG_MAC80211_MESH=y
720CONFIG_MAC80211_LEDS=y
721CONFIG_MAC80211_DEBUGFS=y
722# CONFIG_MAC80211_DEBUG_MENU is not set
723CONFIG_IEEE80211=m
724# CONFIG_IEEE80211_DEBUG is not set
725CONFIG_IEEE80211_CRYPT_WEP=m
726CONFIG_IEEE80211_CRYPT_CCMP=m
727CONFIG_IEEE80211_CRYPT_TKIP=m
728CONFIG_RFKILL=m
729CONFIG_RFKILL_INPUT=m
730CONFIG_RFKILL_LEDS=y
731# CONFIG_NET_9P is not set
732
733#
734# Device Drivers
735#
736
737#
738# Generic Driver Options
739#
740CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
741CONFIG_STANDALONE=y
742CONFIG_PREVENT_FIRMWARE_BUILD=y
743CONFIG_FW_LOADER=y
744CONFIG_FIRMWARE_IN_KERNEL=y
745CONFIG_EXTRA_FIRMWARE=""
746# CONFIG_DEBUG_DRIVER is not set
747CONFIG_DEBUG_DEVRES=y
748# CONFIG_SYS_HYPERVISOR is not set
749CONFIG_CONNECTOR=y
750CONFIG_PROC_EVENTS=y
751# CONFIG_MTD is not set
752# CONFIG_PARPORT is not set
753CONFIG_PNP=y
754# CONFIG_PNP_DEBUG is not set
755
756#
757# Protocols
758#
759CONFIG_PNPACPI=y
760CONFIG_BLK_DEV=y
761# CONFIG_BLK_DEV_FD is not set
762# CONFIG_BLK_CPQ_DA is not set
763# CONFIG_BLK_CPQ_CISS_DA is not set
764# CONFIG_BLK_DEV_DAC960 is not set
765# CONFIG_BLK_DEV_UMEM is not set
766# CONFIG_BLK_DEV_COW_COMMON is not set
767CONFIG_BLK_DEV_LOOP=y
768CONFIG_BLK_DEV_CRYPTOLOOP=m
769# CONFIG_BLK_DEV_NBD is not set
770# CONFIG_BLK_DEV_SX8 is not set
771# CONFIG_BLK_DEV_UB is not set
772CONFIG_BLK_DEV_RAM=y
773CONFIG_BLK_DEV_RAM_COUNT=16
774CONFIG_BLK_DEV_RAM_SIZE=262144
775# CONFIG_BLK_DEV_XIP is not set
776CONFIG_CDROM_PKTCDVD=m
777CONFIG_CDROM_PKTCDVD_BUFFERS=8
778# CONFIG_CDROM_PKTCDVD_WCACHE is not set
779# CONFIG_ATA_OVER_ETH is not set
780# CONFIG_BLK_DEV_HD is not set
781CONFIG_MISC_DEVICES=y
782# CONFIG_IBM_ASM is not set
783# CONFIG_PHANTOM is not set
784CONFIG_EEPROM_93CX6=m
785# CONFIG_SGI_IOC4 is not set
786CONFIG_TIFM_CORE=m
787CONFIG_TIFM_7XX1=m
788# CONFIG_ACER_WMI is not set
789# CONFIG_FUJITSU_LAPTOP is not set
790# CONFIG_TC1100_WMI is not set
791# CONFIG_HP_WMI is not set
792# CONFIG_MSI_LAPTOP is not set
793# CONFIG_COMPAL_LAPTOP is not set
794# CONFIG_SONY_LAPTOP is not set
795# CONFIG_THINKPAD_ACPI is not set
796# CONFIG_INTEL_MENLOW is not set
797CONFIG_EEEPC_LAPTOP=y
798# CONFIG_ENCLOSURE_SERVICES is not set
799# CONFIG_HP_ILO is not set
800CONFIG_HAVE_IDE=y
801# CONFIG_IDE is not set
802
803#
804# SCSI device support
805#
806CONFIG_RAID_ATTRS=m
807CONFIG_SCSI=y
808CONFIG_SCSI_DMA=y
809# CONFIG_SCSI_TGT is not set
810# CONFIG_SCSI_NETLINK is not set
811CONFIG_SCSI_PROC_FS=y
812
813#
814# SCSI support type (disk, tape, CD-ROM)
815#
816CONFIG_BLK_DEV_SD=y
817CONFIG_CHR_DEV_ST=m
818# CONFIG_CHR_DEV_OSST is not set
819CONFIG_BLK_DEV_SR=y
820CONFIG_BLK_DEV_SR_VENDOR=y
821# CONFIG_CHR_DEV_SG is not set
822CONFIG_CHR_DEV_SCH=m
823
824#
825# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
826#
827CONFIG_SCSI_MULTI_LUN=y
828CONFIG_SCSI_CONSTANTS=y
829CONFIG_SCSI_LOGGING=y
830CONFIG_SCSI_SCAN_ASYNC=y
831CONFIG_SCSI_WAIT_SCAN=m
832
833#
834# SCSI Transports
835#
836# CONFIG_SCSI_SPI_ATTRS is not set
837# CONFIG_SCSI_FC_ATTRS is not set
838# CONFIG_SCSI_ISCSI_ATTRS is not set
839# CONFIG_SCSI_SAS_ATTRS is not set
840# CONFIG_SCSI_SAS_LIBSAS is not set
841# CONFIG_SCSI_SRP_ATTRS is not set
842CONFIG_SCSI_LOWLEVEL=y
843# CONFIG_ISCSI_TCP is not set
844# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
845# CONFIG_SCSI_3W_9XXX is not set
846# CONFIG_SCSI_ACARD is not set
847# CONFIG_SCSI_AACRAID is not set
848# CONFIG_SCSI_AIC7XXX is not set
849# CONFIG_SCSI_AIC7XXX_OLD is not set
850# CONFIG_SCSI_AIC79XX is not set
851# CONFIG_SCSI_AIC94XX is not set
852# CONFIG_SCSI_DPT_I2O is not set
853# CONFIG_SCSI_ADVANSYS is not set
854# CONFIG_SCSI_ARCMSR is not set
855# CONFIG_MEGARAID_NEWGEN is not set
856# CONFIG_MEGARAID_LEGACY is not set
857# CONFIG_MEGARAID_SAS is not set
858# CONFIG_SCSI_HPTIOP is not set
859# CONFIG_SCSI_BUSLOGIC is not set
860# CONFIG_SCSI_DMX3191D is not set
861# CONFIG_SCSI_EATA is not set
862# CONFIG_SCSI_FUTURE_DOMAIN is not set
863# CONFIG_SCSI_GDTH is not set
864# CONFIG_SCSI_IPS is not set
865# CONFIG_SCSI_INITIO is not set
866# CONFIG_SCSI_INIA100 is not set
867# CONFIG_SCSI_MVSAS is not set
868# CONFIG_SCSI_STEX is not set
869# CONFIG_SCSI_SYM53C8XX_2 is not set
870# CONFIG_SCSI_IPR is not set
871# CONFIG_SCSI_QLOGIC_1280 is not set
872# CONFIG_SCSI_QLA_FC is not set
873# CONFIG_SCSI_QLA_ISCSI is not set
874# CONFIG_SCSI_LPFC is not set
875# CONFIG_SCSI_DC395x is not set
876# CONFIG_SCSI_DC390T is not set
877# CONFIG_SCSI_NSP32 is not set
878# CONFIG_SCSI_DEBUG is not set
879# CONFIG_SCSI_SRP is not set
880# CONFIG_SCSI_DH is not set
881CONFIG_ATA=y
882# CONFIG_ATA_NONSTANDARD is not set
883CONFIG_ATA_ACPI=y
884# CONFIG_SATA_PMP is not set
885CONFIG_SATA_AHCI=y
886# CONFIG_SATA_SIL24 is not set
887CONFIG_ATA_SFF=y
888# CONFIG_SATA_SVW is not set
889CONFIG_ATA_PIIX=y
890# CONFIG_SATA_MV is not set
891# CONFIG_SATA_NV is not set
892# CONFIG_PDC_ADMA is not set
893# CONFIG_SATA_QSTOR is not set
894# CONFIG_SATA_PROMISE is not set
895# CONFIG_SATA_SX4 is not set
896# CONFIG_SATA_SIL is not set
897# CONFIG_SATA_SIS is not set
898# CONFIG_SATA_ULI is not set
899# CONFIG_SATA_VIA is not set
900# CONFIG_SATA_VITESSE is not set
901# CONFIG_SATA_INIC162X is not set
902# CONFIG_PATA_ACPI is not set
903# CONFIG_PATA_ALI is not set
904# CONFIG_PATA_AMD is not set
905# CONFIG_PATA_ARTOP is not set
906# CONFIG_PATA_ATIIXP is not set
907# CONFIG_PATA_CMD640_PCI is not set
908# CONFIG_PATA_CMD64X is not set
909# CONFIG_PATA_CS5520 is not set
910# CONFIG_PATA_CS5530 is not set
911# CONFIG_PATA_CS5535 is not set
912# CONFIG_PATA_CS5536 is not set
913# CONFIG_PATA_CYPRESS is not set
914# CONFIG_PATA_EFAR is not set
915# CONFIG_ATA_GENERIC is not set
916# CONFIG_PATA_HPT366 is not set
917# CONFIG_PATA_HPT37X is not set
918# CONFIG_PATA_HPT3X2N is not set
919# CONFIG_PATA_HPT3X3 is not set
920# CONFIG_PATA_IT821X is not set
921# CONFIG_PATA_IT8213 is not set
922# CONFIG_PATA_JMICRON is not set
923# CONFIG_PATA_TRIFLEX is not set
924# CONFIG_PATA_MARVELL is not set
925# CONFIG_PATA_MPIIX is not set
926# CONFIG_PATA_OLDPIIX is not set
927# CONFIG_PATA_NETCELL is not set
928# CONFIG_PATA_NINJA32 is not set
929# CONFIG_PATA_NS87410 is not set
930# CONFIG_PATA_NS87415 is not set
931# CONFIG_PATA_OPTI is not set
932# CONFIG_PATA_OPTIDMA is not set
933# CONFIG_PATA_PDC_OLD is not set
934# CONFIG_PATA_RADISYS is not set
935# CONFIG_PATA_RZ1000 is not set
936# CONFIG_PATA_SC1200 is not set
937# CONFIG_PATA_SERVERWORKS is not set
938# CONFIG_PATA_PDC2027X is not set
939# CONFIG_PATA_SIL680 is not set
940# CONFIG_PATA_SIS is not set
941# CONFIG_PATA_VIA is not set
942# CONFIG_PATA_WINBOND is not set
943CONFIG_PATA_SCH=y
944# CONFIG_MD is not set
945# CONFIG_FUSION is not set
946
947#
948# IEEE 1394 (FireWire) support
949#
950
951#
952# Enable only one of the two stacks, unless you know what you are doing
953#
954# CONFIG_FIREWIRE is not set
955# CONFIG_IEEE1394 is not set
956# CONFIG_I2O is not set
957# CONFIG_MACINTOSH_DRIVERS is not set
958CONFIG_NETDEVICES=y
959# CONFIG_DUMMY is not set
960# CONFIG_BONDING is not set
961CONFIG_MACVLAN=m
962# CONFIG_EQUALIZER is not set
963# CONFIG_TUN is not set
964# CONFIG_VETH is not set
965# CONFIG_NET_SB1000 is not set
966# CONFIG_ARCNET is not set
967CONFIG_PHYLIB=m
968
969#
970# MII PHY device drivers
971#
972CONFIG_MARVELL_PHY=m
973CONFIG_DAVICOM_PHY=m
974CONFIG_QSEMI_PHY=m
975CONFIG_LXT_PHY=m
976CONFIG_CICADA_PHY=m
977CONFIG_VITESSE_PHY=m
978CONFIG_SMSC_PHY=m
979CONFIG_BROADCOM_PHY=m
980CONFIG_ICPLUS_PHY=m
981CONFIG_REALTEK_PHY=m
982CONFIG_MDIO_BITBANG=m
983CONFIG_NET_ETHERNET=y
984CONFIG_MII=m
985CONFIG_HAPPYMEAL=m
986CONFIG_SUNGEM=m
987CONFIG_CASSINI=m
988CONFIG_NET_VENDOR_3COM=y
989# CONFIG_VORTEX is not set
990# CONFIG_TYPHOON is not set
991# CONFIG_NET_TULIP is not set
992# CONFIG_HP100 is not set
993# CONFIG_IBM_NEW_EMAC_ZMII is not set
994# CONFIG_IBM_NEW_EMAC_RGMII is not set
995# CONFIG_IBM_NEW_EMAC_TAH is not set
996# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
997# CONFIG_NET_PCI is not set
998# CONFIG_B44 is not set
999CONFIG_NETDEV_1000=y
1000# CONFIG_ACENIC is not set
1001# CONFIG_DL2K is not set
1002# CONFIG_E1000 is not set
1003# CONFIG_E1000E is not set
1004# CONFIG_IP1000 is not set
1005# CONFIG_IGB is not set
1006# CONFIG_NS83820 is not set
1007# CONFIG_HAMACHI is not set
1008# CONFIG_YELLOWFIN is not set
1009# CONFIG_R8169 is not set
1010# CONFIG_SIS190 is not set
1011# CONFIG_SKGE is not set
1012# CONFIG_SKY2 is not set
1013# CONFIG_VIA_VELOCITY is not set
1014# CONFIG_TIGON3 is not set
1015# CONFIG_BNX2 is not set
1016# CONFIG_QLA3XXX is not set
1017CONFIG_ATL1=m
1018CONFIG_ATL1E=m
1019# CONFIG_NETDEV_10000 is not set
1020# CONFIG_TR is not set
1021
1022#
1023# Wireless LAN
1024#
1025CONFIG_WLAN_PRE80211=y
1026# CONFIG_STRIP is not set
1027CONFIG_WLAN_80211=y
1028# CONFIG_IPW2100 is not set
1029# CONFIG_IPW2200 is not set
1030# CONFIG_LIBERTAS is not set
1031# CONFIG_AIRO is not set
1032# CONFIG_HERMES is not set
1033# CONFIG_ATMEL is not set
1034# CONFIG_PRISM54 is not set
1035CONFIG_USB_ZD1201=m
1036CONFIG_USB_NET_RNDIS_WLAN=m
1037CONFIG_RTL8180=m
1038CONFIG_RTL8187=m
1039# CONFIG_ADM8211 is not set
1040# CONFIG_MAC80211_HWSIM is not set
1041# CONFIG_P54_COMMON is not set
1042CONFIG_ATH5K=m
1043# CONFIG_ATH5K_DEBUG is not set
1044# CONFIG_ATH9K is not set
1045CONFIG_IWLWIFI=m
1046CONFIG_IWLCORE=m
1047# CONFIG_IWLWIFI_LEDS is not set
1048CONFIG_IWLWIFI_RFKILL=y
1049# CONFIG_IWLWIFI_DEBUG is not set
1050# CONFIG_IWLAGN is not set
1051CONFIG_IWL3945=m
1052CONFIG_IWL3945_RFKILL=y
1053# CONFIG_IWL3945_SPECTRUM_MEASUREMENT is not set
1054# CONFIG_IWL3945_LEDS is not set
1055# CONFIG_IWL3945_DEBUG is not set
1056# CONFIG_HOSTAP is not set
1057# CONFIG_B43 is not set
1058# CONFIG_B43LEGACY is not set
1059# CONFIG_ZD1211RW is not set
1060CONFIG_RT2X00=m
1061CONFIG_RT2X00_LIB=m
1062CONFIG_RT2X00_LIB_PCI=m
1063CONFIG_RT2X00_LIB_USB=m
1064CONFIG_RT2X00_LIB_FIRMWARE=y
1065CONFIG_RT2X00_LIB_RFKILL=y
1066CONFIG_RT2X00_LIB_LEDS=y
1067CONFIG_RT2400PCI=m
1068CONFIG_RT2400PCI_RFKILL=y
1069CONFIG_RT2400PCI_LEDS=y
1070CONFIG_RT2500PCI=m
1071CONFIG_RT2500PCI_RFKILL=y
1072CONFIG_RT2500PCI_LEDS=y
1073CONFIG_RT61PCI=m
1074CONFIG_RT61PCI_RFKILL=y
1075CONFIG_RT61PCI_LEDS=y
1076CONFIG_RT2500USB=m
1077CONFIG_RT2500USB_LEDS=y
1078CONFIG_RT73USB=m
1079CONFIG_RT73USB_LEDS=y
1080CONFIG_RT2X00_LIB_DEBUGFS=y
1081# CONFIG_RT2X00_DEBUG is not set
1082
1083#
1084# USB Network Adapters
1085#
1086CONFIG_USB_CATC=m
1087CONFIG_USB_KAWETH=m
1088CONFIG_USB_PEGASUS=m
1089CONFIG_USB_RTL8150=m
1090CONFIG_USB_USBNET=m
1091CONFIG_USB_NET_AX8817X=m
1092CONFIG_USB_NET_CDCETHER=m
1093CONFIG_USB_NET_DM9601=m
1094CONFIG_USB_NET_GL620A=m
1095CONFIG_USB_NET_NET1080=m
1096CONFIG_USB_NET_PLUSB=m
1097CONFIG_USB_NET_MCS7830=m
1098CONFIG_USB_NET_RNDIS_HOST=m
1099CONFIG_USB_NET_CDC_SUBSET=m
1100CONFIG_USB_ALI_M5632=y
1101CONFIG_USB_AN2720=y
1102CONFIG_USB_BELKIN=y
1103CONFIG_USB_ARMLINUX=y
1104CONFIG_USB_EPSON2888=y
1105CONFIG_USB_KC2190=y
1106CONFIG_USB_NET_ZAURUS=m
1107# CONFIG_USB_HSO is not set
1108# CONFIG_WAN is not set
1109# CONFIG_FDDI is not set
1110# CONFIG_HIPPI is not set
1111CONFIG_PPP=m
1112CONFIG_PPP_MULTILINK=y
1113CONFIG_PPP_FILTER=y
1114CONFIG_PPP_ASYNC=m
1115CONFIG_PPP_SYNC_TTY=m
1116CONFIG_PPP_DEFLATE=m
1117# CONFIG_PPP_BSDCOMP is not set
1118CONFIG_PPP_MPPE=m
1119CONFIG_PPPOE=m
1120CONFIG_PPPOL2TP=m
1121# CONFIG_SLIP is not set
1122CONFIG_SLHC=m
1123CONFIG_NET_FC=y
1124CONFIG_NETCONSOLE=m
1125CONFIG_NETCONSOLE_DYNAMIC=y
1126CONFIG_NETPOLL=y
1127CONFIG_NETPOLL_TRAP=y
1128CONFIG_NET_POLL_CONTROLLER=y
1129# CONFIG_ISDN is not set
1130# CONFIG_PHONE is not set
1131
1132#
1133# Input device support
1134#
1135CONFIG_INPUT=y
1136CONFIG_INPUT_FF_MEMLESS=y
1137CONFIG_INPUT_POLLDEV=m
1138
1139#
1140# Userland interfaces
1141#
1142CONFIG_INPUT_MOUSEDEV=y
1143# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
1144CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
1145CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
1146CONFIG_INPUT_JOYDEV=m
1147CONFIG_INPUT_EVDEV=y
1148# CONFIG_INPUT_EVBUG is not set
1149
1150#
1151# Input Device Drivers
1152#
1153CONFIG_INPUT_KEYBOARD=y
1154CONFIG_KEYBOARD_ATKBD=y
1155# CONFIG_KEYBOARD_SUNKBD is not set
1156# CONFIG_KEYBOARD_LKKBD is not set
1157# CONFIG_KEYBOARD_XTKBD is not set
1158# CONFIG_KEYBOARD_NEWTON is not set
1159# CONFIG_KEYBOARD_STOWAWAY is not set
1160CONFIG_INPUT_MOUSE=y
1161CONFIG_MOUSE_PS2=y
1162CONFIG_MOUSE_PS2_ALPS=y
1163CONFIG_MOUSE_PS2_LOGIPS2PP=y
1164CONFIG_MOUSE_PS2_SYNAPTICS=y
1165CONFIG_MOUSE_PS2_LIFEBOOK=y
1166CONFIG_MOUSE_PS2_TRACKPOINT=y
1167# CONFIG_MOUSE_PS2_TOUCHKIT is not set
1168CONFIG_MOUSE_SERIAL=m
1169# CONFIG_MOUSE_APPLETOUCH is not set
1170# CONFIG_MOUSE_BCM5974 is not set
1171CONFIG_MOUSE_VSXXXAA=m
1172CONFIG_INPUT_JOYSTICK=y
1173# CONFIG_JOYSTICK_ANALOG is not set
1174# CONFIG_JOYSTICK_A3D is not set
1175# CONFIG_JOYSTICK_ADI is not set
1176# CONFIG_JOYSTICK_COBRA is not set
1177# CONFIG_JOYSTICK_GF2K is not set
1178# CONFIG_JOYSTICK_GRIP is not set
1179# CONFIG_JOYSTICK_GRIP_MP is not set
1180# CONFIG_JOYSTICK_GUILLEMOT is not set
1181# CONFIG_JOYSTICK_INTERACT is not set
1182# CONFIG_JOYSTICK_SIDEWINDER is not set
1183# CONFIG_JOYSTICK_TMDC is not set
1184# CONFIG_JOYSTICK_IFORCE is not set
1185# CONFIG_JOYSTICK_WARRIOR is not set
1186# CONFIG_JOYSTICK_MAGELLAN is not set
1187# CONFIG_JOYSTICK_SPACEORB is not set
1188# CONFIG_JOYSTICK_SPACEBALL is not set
1189# CONFIG_JOYSTICK_STINGER is not set
1190# CONFIG_JOYSTICK_TWIDJOY is not set
1191# CONFIG_JOYSTICK_ZHENHUA is not set
1192# CONFIG_JOYSTICK_JOYDUMP is not set
1193# CONFIG_JOYSTICK_XPAD is not set
1194# CONFIG_INPUT_TABLET is not set
1195CONFIG_INPUT_TOUCHSCREEN=y
1196CONFIG_TOUCHSCREEN_FUJITSU=m
1197CONFIG_TOUCHSCREEN_GUNZE=m
1198CONFIG_TOUCHSCREEN_ELO=m
1199CONFIG_TOUCHSCREEN_MTOUCH=m
1200CONFIG_TOUCHSCREEN_INEXIO=m
1201CONFIG_TOUCHSCREEN_MK712=m
1202CONFIG_TOUCHSCREEN_PENMOUNT=m
1203CONFIG_TOUCHSCREEN_TOUCHRIGHT=m
1204CONFIG_TOUCHSCREEN_TOUCHWIN=m
1205CONFIG_TOUCHSCREEN_UCB1400=m
1206# CONFIG_TOUCHSCREEN_WM97XX is not set
1207CONFIG_TOUCHSCREEN_USB_COMPOSITE=m
1208CONFIG_TOUCHSCREEN_USB_EGALAX=y
1209CONFIG_TOUCHSCREEN_USB_PANJIT=y
1210CONFIG_TOUCHSCREEN_USB_3M=y
1211CONFIG_TOUCHSCREEN_USB_ITM=y
1212CONFIG_TOUCHSCREEN_USB_ETURBO=y
1213CONFIG_TOUCHSCREEN_USB_GUNZE=y
1214CONFIG_TOUCHSCREEN_USB_DMC_TSC10=y
1215CONFIG_TOUCHSCREEN_USB_IRTOUCH=y
1216CONFIG_TOUCHSCREEN_USB_IDEALTEK=y
1217CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH=y
1218CONFIG_TOUCHSCREEN_USB_GOTOP=y
1219CONFIG_TOUCHSCREEN_TOUCHIT213=m
1220CONFIG_INPUT_MISC=y
1221# CONFIG_INPUT_PCSPKR is not set
1222# CONFIG_INPUT_APANEL is not set
1223# CONFIG_INPUT_WISTRON_BTNS is not set
1224CONFIG_INPUT_ATLAS_BTNS=m
1225CONFIG_INPUT_ATI_REMOTE=m
1226CONFIG_INPUT_ATI_REMOTE2=m
1227CONFIG_INPUT_KEYSPAN_REMOTE=m
1228CONFIG_INPUT_POWERMATE=m
1229CONFIG_INPUT_YEALINK=m
1230CONFIG_INPUT_UINPUT=m
1231
1232#
1233# Hardware I/O ports
1234#
1235CONFIG_SERIO=y
1236CONFIG_SERIO_I8042=y
1237CONFIG_SERIO_SERPORT=y
1238# CONFIG_SERIO_CT82C710 is not set
1239# CONFIG_SERIO_PCIPS2 is not set
1240CONFIG_SERIO_LIBPS2=y
1241CONFIG_SERIO_RAW=m
1242# CONFIG_GAMEPORT is not set
1243
1244#
1245# Character devices
1246#
1247CONFIG_VT=y
1248CONFIG_CONSOLE_TRANSLATIONS=y
1249CONFIG_VT_CONSOLE=y
1250CONFIG_HW_CONSOLE=y
1251CONFIG_VT_HW_CONSOLE_BINDING=y
1252# CONFIG_DEVKMEM is not set
1253# CONFIG_SERIAL_NONSTANDARD is not set
1254# CONFIG_NOZOMI is not set
1255
1256#
1257# Serial drivers
1258#
1259# CONFIG_SERIAL_8250 is not set
1260CONFIG_FIX_EARLYCON_MEM=y
1261
1262#
1263# Non-8250 serial port support
1264#
1265# CONFIG_SERIAL_JSM is not set
1266CONFIG_UNIX98_PTYS=y
1267# CONFIG_LEGACY_PTYS is not set
1268# CONFIG_IPMI_HANDLER is not set
1269# CONFIG_HW_RANDOM is not set
1270# CONFIG_NVRAM is not set
1271# CONFIG_R3964 is not set
1272# CONFIG_APPLICOM is not set
1273# CONFIG_SONYPI is not set
1274# CONFIG_MWAVE is not set
1275# CONFIG_PC8736x_GPIO is not set
1276# CONFIG_NSC_GPIO is not set
1277# CONFIG_CS5535_GPIO is not set
1278# CONFIG_RAW_DRIVER is not set
1279CONFIG_HPET=y
1280# CONFIG_HPET_MMAP is not set
1281# CONFIG_HANGCHECK_TIMER is not set
1282# CONFIG_TCG_TPM is not set
1283# CONFIG_TELCLOCK is not set
1284CONFIG_DEVPORT=y
1285CONFIG_I2C=y
1286CONFIG_I2C_BOARDINFO=y
1287# CONFIG_I2C_CHARDEV is not set
1288CONFIG_I2C_HELPER_AUTO=y
1289CONFIG_I2C_ALGOBIT=y
1290
1291#
1292# I2C Hardware Bus support
1293#
1294
1295#
1296# PC SMBus host controller drivers
1297#
1298# CONFIG_I2C_ALI1535 is not set
1299# CONFIG_I2C_ALI1563 is not set
1300# CONFIG_I2C_ALI15X3 is not set
1301# CONFIG_I2C_AMD756 is not set
1302# CONFIG_I2C_AMD8111 is not set
1303# CONFIG_I2C_I801 is not set
1304# CONFIG_I2C_ISCH is not set
1305# CONFIG_I2C_PIIX4 is not set
1306# CONFIG_I2C_NFORCE2 is not set
1307# CONFIG_I2C_SIS5595 is not set
1308# CONFIG_I2C_SIS630 is not set
1309# CONFIG_I2C_SIS96X is not set
1310# CONFIG_I2C_VIA is not set
1311# CONFIG_I2C_VIAPRO is not set
1312
1313#
1314# I2C system bus drivers (mostly embedded / system-on-chip)
1315#
1316# CONFIG_I2C_OCORES is not set
1317# CONFIG_I2C_SIMTEC is not set
1318
1319#
1320# External I2C/SMBus adapter drivers
1321#
1322# CONFIG_I2C_PARPORT_LIGHT is not set
1323# CONFIG_I2C_TAOS_EVM is not set
1324# CONFIG_I2C_TINY_USB is not set
1325
1326#
1327# Graphics adapter I2C/DDC channel drivers
1328#
1329# CONFIG_I2C_VOODOO3 is not set
1330
1331#
1332# Other I2C/SMBus bus drivers
1333#
1334# CONFIG_I2C_PCA_PLATFORM is not set
1335# CONFIG_I2C_STUB is not set
1336# CONFIG_SCx200_ACB is not set
1337
1338#
1339# Miscellaneous I2C Chip support
1340#
1341# CONFIG_DS1682 is not set
1342# CONFIG_AT24 is not set
1343# CONFIG_SENSORS_EEPROM is not set
1344# CONFIG_SENSORS_PCF8574 is not set
1345# CONFIG_PCF8575 is not set
1346# CONFIG_SENSORS_PCA9539 is not set
1347# CONFIG_SENSORS_PCF8591 is not set
1348# CONFIG_SENSORS_MAX6875 is not set
1349# CONFIG_SENSORS_TSL2550 is not set
1350# CONFIG_I2C_DEBUG_CORE is not set
1351# CONFIG_I2C_DEBUG_ALGO is not set
1352# CONFIG_I2C_DEBUG_BUS is not set
1353# CONFIG_I2C_DEBUG_CHIP is not set
1354# CONFIG_SPI is not set
1355CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
1356# CONFIG_GPIOLIB is not set
1357# CONFIG_W1 is not set
1358CONFIG_POWER_SUPPLY=y
1359# CONFIG_POWER_SUPPLY_DEBUG is not set
1360# CONFIG_PDA_POWER is not set
1361# CONFIG_BATTERY_DS2760 is not set
1362CONFIG_HWMON=y
1363# CONFIG_HWMON_VID is not set
1364# CONFIG_SENSORS_ABITUGURU is not set
1365# CONFIG_SENSORS_ABITUGURU3 is not set
1366# CONFIG_SENSORS_AD7414 is not set
1367# CONFIG_SENSORS_AD7418 is not set
1368# CONFIG_SENSORS_ADM1021 is not set
1369# CONFIG_SENSORS_ADM1025 is not set
1370# CONFIG_SENSORS_ADM1026 is not set
1371# CONFIG_SENSORS_ADM1029 is not set
1372# CONFIG_SENSORS_ADM1031 is not set
1373# CONFIG_SENSORS_ADM9240 is not set
1374# CONFIG_SENSORS_ADT7470 is not set
1375# CONFIG_SENSORS_ADT7473 is not set
1376# CONFIG_SENSORS_K8TEMP is not set
1377# CONFIG_SENSORS_ASB100 is not set
1378# CONFIG_SENSORS_ATXP1 is not set
1379# CONFIG_SENSORS_DS1621 is not set
1380# CONFIG_SENSORS_I5K_AMB is not set
1381# CONFIG_SENSORS_F71805F is not set
1382# CONFIG_SENSORS_F71882FG is not set
1383# CONFIG_SENSORS_F75375S is not set
1384# CONFIG_SENSORS_FSCHER is not set
1385# CONFIG_SENSORS_FSCPOS is not set
1386# CONFIG_SENSORS_FSCHMD is not set
1387# CONFIG_SENSORS_GL518SM is not set
1388# CONFIG_SENSORS_GL520SM is not set
1389# CONFIG_SENSORS_CORETEMP is not set
1390# CONFIG_SENSORS_IT87 is not set
1391# CONFIG_SENSORS_LM63 is not set
1392# CONFIG_SENSORS_LM75 is not set
1393# CONFIG_SENSORS_LM77 is not set
1394# CONFIG_SENSORS_LM78 is not set
1395# CONFIG_SENSORS_LM80 is not set
1396# CONFIG_SENSORS_LM83 is not set
1397# CONFIG_SENSORS_LM85 is not set
1398# CONFIG_SENSORS_LM87 is not set
1399# CONFIG_SENSORS_LM90 is not set
1400# CONFIG_SENSORS_LM92 is not set
1401# CONFIG_SENSORS_LM93 is not set
1402# CONFIG_SENSORS_MAX1619 is not set
1403# CONFIG_SENSORS_MAX6650 is not set
1404# CONFIG_SENSORS_PC87360 is not set
1405# CONFIG_SENSORS_PC87427 is not set
1406# CONFIG_SENSORS_SIS5595 is not set
1407# CONFIG_SENSORS_DME1737 is not set
1408# CONFIG_SENSORS_SMSC47M1 is not set
1409# CONFIG_SENSORS_SMSC47M192 is not set
1410# CONFIG_SENSORS_SMSC47B397 is not set
1411# CONFIG_SENSORS_ADS7828 is not set
1412# CONFIG_SENSORS_THMC50 is not set
1413# CONFIG_SENSORS_VIA686A is not set
1414# CONFIG_SENSORS_VT1211 is not set
1415# CONFIG_SENSORS_VT8231 is not set
1416# CONFIG_SENSORS_W83781D is not set
1417# CONFIG_SENSORS_W83791D is not set
1418# CONFIG_SENSORS_W83792D is not set
1419# CONFIG_SENSORS_W83793 is not set
1420# CONFIG_SENSORS_W83L785TS is not set
1421# CONFIG_SENSORS_W83L786NG is not set
1422# CONFIG_SENSORS_W83627HF is not set
1423# CONFIG_SENSORS_W83627EHF is not set
1424# CONFIG_SENSORS_HDAPS is not set
1425# CONFIG_SENSORS_APPLESMC is not set
1426# CONFIG_HWMON_DEBUG_CHIP is not set
1427CONFIG_THERMAL=y
1428# CONFIG_THERMAL_HWMON is not set
1429# CONFIG_WATCHDOG is not set
1430
1431#
1432# Sonics Silicon Backplane
1433#
1434CONFIG_SSB_POSSIBLE=y
1435# CONFIG_SSB is not set
1436
1437#
1438# Multifunction device drivers
1439#
1440# CONFIG_MFD_CORE is not set
1441# CONFIG_MFD_SM501 is not set
1442# CONFIG_HTC_PASIC3 is not set
1443# CONFIG_MFD_TMIO is not set
1444
1445#
1446# Multimedia devices
1447#
1448
1449#
1450# Multimedia core support
1451#
1452CONFIG_VIDEO_DEV=y
1453CONFIG_VIDEO_V4L2_COMMON=y
1454# CONFIG_VIDEO_ALLOW_V4L1 is not set
1455CONFIG_VIDEO_V4L1_COMPAT=y
1456CONFIG_DVB_CORE=y
1457CONFIG_VIDEO_MEDIA=y
1458
1459#
1460# Multimedia drivers
1461#
1462# CONFIG_MEDIA_ATTACH is not set
1463CONFIG_MEDIA_TUNER=y
1464# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set
1465CONFIG_MEDIA_TUNER_SIMPLE=y
1466CONFIG_MEDIA_TUNER_TDA8290=y
1467CONFIG_MEDIA_TUNER_TDA9887=y
1468CONFIG_MEDIA_TUNER_TEA5761=y
1469CONFIG_MEDIA_TUNER_TEA5767=y
1470CONFIG_MEDIA_TUNER_MT20XX=y
1471CONFIG_MEDIA_TUNER_XC2028=y
1472CONFIG_MEDIA_TUNER_XC5000=y
1473CONFIG_VIDEO_V4L2=y
1474CONFIG_VIDEO_CAPTURE_DRIVERS=y
1475# CONFIG_VIDEO_ADV_DEBUG is not set
1476CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
1477# CONFIG_VIDEO_VIVI is not set
1478# CONFIG_VIDEO_BT848 is not set
1479# CONFIG_VIDEO_SAA5246A is not set
1480# CONFIG_VIDEO_SAA5249 is not set
1481# CONFIG_VIDEO_SAA7134 is not set
1482# CONFIG_VIDEO_HEXIUM_ORION is not set
1483# CONFIG_VIDEO_HEXIUM_GEMINI is not set
1484# CONFIG_VIDEO_CX88 is not set
1485# CONFIG_VIDEO_CX23885 is not set
1486# CONFIG_VIDEO_AU0828 is not set
1487# CONFIG_VIDEO_CX18 is not set
1488# CONFIG_VIDEO_CAFE_CCIC is not set
1489CONFIG_V4L_USB_DRIVERS=y
1490CONFIG_USB_VIDEO_CLASS=y
1491CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y
1492# CONFIG_USB_GSPCA is not set
1493# CONFIG_VIDEO_PVRUSB2 is not set
1494# CONFIG_VIDEO_EM28XX is not set
1495# CONFIG_VIDEO_USBVISION is not set
1496# CONFIG_USB_ET61X251 is not set
1497# CONFIG_USB_SN9C102 is not set
1498# CONFIG_USB_ZC0301 is not set
1499# CONFIG_USB_ZR364XX is not set
1500# CONFIG_USB_STKWEBCAM is not set
1501# CONFIG_USB_S2255 is not set
1502# CONFIG_SOC_CAMERA is not set
1503# CONFIG_VIDEO_SH_MOBILE_CEU is not set
1504# CONFIG_RADIO_ADAPTERS is not set
1505# CONFIG_DVB_CAPTURE_DRIVERS is not set
1506# CONFIG_DAB is not set
1507
1508#
1509# Graphics support
1510#
1511CONFIG_AGP=y
1512# CONFIG_AGP_ALI is not set
1513# CONFIG_AGP_ATI is not set
1514# CONFIG_AGP_AMD is not set
1515CONFIG_AGP_AMD64=y
1516CONFIG_AGP_INTEL=y
1517# CONFIG_AGP_NVIDIA is not set
1518# CONFIG_AGP_SIS is not set
1519# CONFIG_AGP_SWORKS is not set
1520# CONFIG_AGP_VIA is not set
1521# CONFIG_AGP_EFFICEON is not set
1522CONFIG_DRM=y
1523# CONFIG_DRM_TDFX is not set
1524# CONFIG_DRM_R128 is not set
1525# CONFIG_DRM_RADEON is not set
1526CONFIG_DRM_I810=y
1527# CONFIG_DRM_I830 is not set
1528CONFIG_DRM_I915=y
1529# CONFIG_DRM_MGA is not set
1530# CONFIG_DRM_SIS is not set
1531# CONFIG_DRM_VIA is not set
1532# CONFIG_DRM_SAVAGE is not set
1533# CONFIG_VGASTATE is not set
1534CONFIG_VIDEO_OUTPUT_CONTROL=y
1535CONFIG_FB=y
1536CONFIG_FIRMWARE_EDID=y
1537CONFIG_FB_DDC=y
1538CONFIG_FB_CFB_FILLRECT=y
1539CONFIG_FB_CFB_COPYAREA=y
1540CONFIG_FB_CFB_IMAGEBLIT=y
1541# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
1542# CONFIG_FB_SYS_FILLRECT is not set
1543# CONFIG_FB_SYS_COPYAREA is not set
1544# CONFIG_FB_SYS_IMAGEBLIT is not set
1545# CONFIG_FB_FOREIGN_ENDIAN is not set
1546# CONFIG_FB_SYS_FOPS is not set
1547# CONFIG_FB_SVGALIB is not set
1548# CONFIG_FB_MACMODES is not set
1549# CONFIG_FB_BACKLIGHT is not set
1550CONFIG_FB_MODE_HELPERS=y
1551# CONFIG_FB_TILEBLITTING is not set
1552
1553#
1554# Frame buffer hardware drivers
1555#
1556# CONFIG_FB_CIRRUS is not set
1557# CONFIG_FB_PM2 is not set
1558# CONFIG_FB_CYBER2000 is not set
1559# CONFIG_FB_ARC is not set
1560# CONFIG_FB_ASILIANT is not set
1561# CONFIG_FB_IMSTT is not set
1562# CONFIG_FB_VGA16 is not set
1563# CONFIG_FB_UVESA is not set
1564# CONFIG_FB_VESA is not set
1565# CONFIG_FB_EFI is not set
1566# CONFIG_FB_N411 is not set
1567# CONFIG_FB_HGA is not set
1568# CONFIG_FB_S1D13XXX is not set
1569# CONFIG_FB_NVIDIA is not set
1570# CONFIG_FB_RIVA is not set
1571# CONFIG_FB_I810 is not set
1572# CONFIG_FB_LE80578 is not set
1573CONFIG_FB_INTEL=y
1574CONFIG_FB_INTEL_DEBUG=y
1575CONFIG_FB_INTEL_I2C=y
1576# CONFIG_FB_MATROX is not set
1577# CONFIG_FB_RADEON is not set
1578# CONFIG_FB_ATY128 is not set
1579# CONFIG_FB_ATY is not set
1580# CONFIG_FB_S3 is not set
1581# CONFIG_FB_SAVAGE is not set
1582# CONFIG_FB_SIS is not set
1583# CONFIG_FB_NEOMAGIC is not set
1584# CONFIG_FB_KYRO is not set
1585# CONFIG_FB_3DFX is not set
1586# CONFIG_FB_VOODOO1 is not set
1587# CONFIG_FB_VT8623 is not set
1588# CONFIG_FB_CYBLA is not set
1589# CONFIG_FB_TRIDENT is not set
1590# CONFIG_FB_ARK is not set
1591# CONFIG_FB_PM3 is not set
1592# CONFIG_FB_CARMINE is not set
1593# CONFIG_FB_GEODE is not set
1594# CONFIG_FB_VIRTUAL is not set
1595CONFIG_BACKLIGHT_LCD_SUPPORT=y
1596CONFIG_LCD_CLASS_DEVICE=y
1597# CONFIG_LCD_ILI9320 is not set
1598CONFIG_LCD_PLATFORM=y
1599CONFIG_BACKLIGHT_CLASS_DEVICE=y
1600# CONFIG_BACKLIGHT_CORGI is not set
1601# CONFIG_BACKLIGHT_PROGEAR is not set
1602CONFIG_BACKLIGHT_MBP_NVIDIA=y
1603
1604#
1605# Display device support
1606#
1607CONFIG_DISPLAY_SUPPORT=y
1608
1609#
1610# Display hardware drivers
1611#
1612
1613#
1614# Console display driver support
1615#
1616CONFIG_VGA_CONSOLE=y
1617CONFIG_VGACON_SOFT_SCROLLBACK=y
1618CONFIG_VGACON_SOFT_SCROLLBACK_SIZE=64
1619CONFIG_VIDEO_SELECT=y
1620CONFIG_DUMMY_CONSOLE=y
1621CONFIG_FRAMEBUFFER_CONSOLE=y
1622# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
1623# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
1624# CONFIG_FONTS is not set
1625CONFIG_FONT_8x8=y
1626CONFIG_FONT_8x16=y
1627# CONFIG_LOGO is not set
1628CONFIG_SOUND=y
1629CONFIG_SND=y
1630CONFIG_SND_TIMER=y
1631CONFIG_SND_PCM=y
1632CONFIG_SND_HWDEP=y
1633CONFIG_SND_RAWMIDI=m
1634CONFIG_SND_SEQUENCER=y
1635CONFIG_SND_SEQ_DUMMY=y
1636# CONFIG_SND_MIXER_OSS is not set
1637# CONFIG_SND_PCM_OSS is not set
1638# CONFIG_SND_SEQUENCER_OSS is not set
1639CONFIG_SND_DYNAMIC_MINORS=y
1640# CONFIG_SND_SUPPORT_OLD_API is not set
1641CONFIG_SND_VERBOSE_PROCFS=y
1642CONFIG_SND_VERBOSE_PRINTK=y
1643CONFIG_SND_DEBUG=y
1644# CONFIG_SND_DEBUG_VERBOSE is not set
1645CONFIG_SND_PCM_XRUN_DEBUG=y
1646CONFIG_SND_VMASTER=y
1647CONFIG_SND_AC97_CODEC=y
1648CONFIG_SND_DRIVERS=y
1649# CONFIG_SND_PCSP is not set
1650# CONFIG_SND_DUMMY is not set
1651# CONFIG_SND_VIRMIDI is not set
1652# CONFIG_SND_MTPAV is not set
1653# CONFIG_SND_SERIAL_U16550 is not set
1654# CONFIG_SND_MPU401 is not set
1655CONFIG_SND_AC97_POWER_SAVE=y
1656CONFIG_SND_AC97_POWER_SAVE_DEFAULT=5
1657CONFIG_SND_PCI=y
1658# CONFIG_SND_AD1889 is not set
1659# CONFIG_SND_ALS300 is not set
1660# CONFIG_SND_ALS4000 is not set
1661# CONFIG_SND_ALI5451 is not set
1662# CONFIG_SND_ATIIXP is not set
1663# CONFIG_SND_ATIIXP_MODEM is not set
1664# CONFIG_SND_AU8810 is not set
1665# CONFIG_SND_AU8820 is not set
1666# CONFIG_SND_AU8830 is not set
1667# CONFIG_SND_AW2 is not set
1668# CONFIG_SND_AZT3328 is not set
1669# CONFIG_SND_BT87X is not set
1670# CONFIG_SND_CA0106 is not set
1671# CONFIG_SND_CMIPCI is not set
1672# CONFIG_SND_OXYGEN is not set
1673# CONFIG_SND_CS4281 is not set
1674# CONFIG_SND_CS46XX is not set
1675# CONFIG_SND_CS5530 is not set
1676# CONFIG_SND_CS5535AUDIO is not set
1677# CONFIG_SND_DARLA20 is not set
1678# CONFIG_SND_GINA20 is not set
1679# CONFIG_SND_LAYLA20 is not set
1680# CONFIG_SND_DARLA24 is not set
1681# CONFIG_SND_GINA24 is not set
1682# CONFIG_SND_LAYLA24 is not set
1683# CONFIG_SND_MONA is not set
1684# CONFIG_SND_MIA is not set
1685# CONFIG_SND_ECHO3G is not set
1686# CONFIG_SND_INDIGO is not set
1687# CONFIG_SND_INDIGOIO is not set
1688# CONFIG_SND_INDIGODJ is not set
1689# CONFIG_SND_EMU10K1 is not set
1690# CONFIG_SND_EMU10K1X is not set
1691# CONFIG_SND_ENS1370 is not set
1692# CONFIG_SND_ENS1371 is not set
1693# CONFIG_SND_ES1938 is not set
1694# CONFIG_SND_ES1968 is not set
1695# CONFIG_SND_FM801 is not set
1696CONFIG_SND_HDA_INTEL=y
1697CONFIG_SND_HDA_HWDEP=y
1698CONFIG_SND_HDA_CODEC_REALTEK=y
1699CONFIG_SND_HDA_CODEC_ANALOG=y
1700CONFIG_SND_HDA_CODEC_SIGMATEL=y
1701CONFIG_SND_HDA_CODEC_VIA=y
1702CONFIG_SND_HDA_CODEC_ATIHDMI=y
1703CONFIG_SND_HDA_CODEC_CONEXANT=y
1704CONFIG_SND_HDA_CODEC_CMEDIA=y
1705CONFIG_SND_HDA_CODEC_SI3054=y
1706CONFIG_SND_HDA_GENERIC=y
1707CONFIG_SND_HDA_POWER_SAVE=y
1708CONFIG_SND_HDA_POWER_SAVE_DEFAULT=0
1709# CONFIG_SND_HDSP is not set
1710# CONFIG_SND_HDSPM is not set
1711# CONFIG_SND_HIFIER is not set
1712# CONFIG_SND_ICE1712 is not set
1713# CONFIG_SND_ICE1724 is not set
1714CONFIG_SND_INTEL8X0=y
1715# CONFIG_SND_INTEL8X0M is not set
1716# CONFIG_SND_KORG1212 is not set
1717# CONFIG_SND_MAESTRO3 is not set
1718# CONFIG_SND_MIXART is not set
1719# CONFIG_SND_NM256 is not set
1720# CONFIG_SND_PCXHR is not set
1721# CONFIG_SND_RIPTIDE is not set
1722# CONFIG_SND_RME32 is not set
1723# CONFIG_SND_RME96 is not set
1724# CONFIG_SND_RME9652 is not set
1725# CONFIG_SND_SIS7019 is not set
1726# CONFIG_SND_SONICVIBES is not set
1727# CONFIG_SND_TRIDENT is not set
1728# CONFIG_SND_VIA82XX is not set
1729# CONFIG_SND_VIA82XX_MODEM is not set
1730# CONFIG_SND_VIRTUOSO is not set
1731# CONFIG_SND_VX222 is not set
1732# CONFIG_SND_YMFPCI is not set
1733CONFIG_SND_USB=y
1734CONFIG_SND_USB_AUDIO=m
1735CONFIG_SND_USB_USX2Y=m
1736CONFIG_SND_USB_CAIAQ=m
1737CONFIG_SND_USB_CAIAQ_INPUT=y
1738# CONFIG_SND_SOC is not set
1739# CONFIG_SOUND_PRIME is not set
1740CONFIG_AC97_BUS=y
1741CONFIG_HID_SUPPORT=y
1742CONFIG_HID=y
1743CONFIG_HID_DEBUG=y
1744CONFIG_HIDRAW=y
1745
1746#
1747# USB Input Devices
1748#
1749CONFIG_USB_HID=y
1750CONFIG_USB_HIDINPUT_POWERBOOK=y
1751CONFIG_HID_FF=y
1752CONFIG_HID_PID=y
1753CONFIG_LOGITECH_FF=y
1754# CONFIG_LOGIRUMBLEPAD2_FF is not set
1755CONFIG_PANTHERLORD_FF=y
1756CONFIG_THRUSTMASTER_FF=y
1757CONFIG_ZEROPLUS_FF=y
1758CONFIG_USB_HIDDEV=y
1759CONFIG_USB_SUPPORT=y
1760CONFIG_USB_ARCH_HAS_HCD=y
1761CONFIG_USB_ARCH_HAS_OHCI=y
1762CONFIG_USB_ARCH_HAS_EHCI=y
1763CONFIG_USB=y
1764# CONFIG_USB_DEBUG is not set
1765CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
1766
1767#
1768# Miscellaneous USB options
1769#
1770CONFIG_USB_DEVICEFS=y
1771# CONFIG_USB_DEVICE_CLASS is not set
1772# CONFIG_USB_DYNAMIC_MINORS is not set
1773CONFIG_USB_SUSPEND=y
1774# CONFIG_USB_OTG is not set
1775CONFIG_USB_MON=y
1776
1777#
1778# USB Host Controller Drivers
1779#
1780# CONFIG_USB_C67X00_HCD is not set
1781CONFIG_USB_EHCI_HCD=y
1782CONFIG_USB_EHCI_ROOT_HUB_TT=y
1783CONFIG_USB_EHCI_TT_NEWSCHED=y
1784CONFIG_USB_ISP116X_HCD=m
1785# CONFIG_USB_ISP1760_HCD is not set
1786CONFIG_USB_OHCI_HCD=y
1787# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
1788# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
1789CONFIG_USB_OHCI_LITTLE_ENDIAN=y
1790CONFIG_USB_UHCI_HCD=y
1791CONFIG_USB_U132_HCD=m
1792CONFIG_USB_SL811_HCD=m
1793# CONFIG_USB_R8A66597_HCD is not set
1794
1795#
1796# USB Device Class drivers
1797#
1798CONFIG_USB_ACM=m
1799CONFIG_USB_PRINTER=m
1800# CONFIG_USB_WDM is not set
1801
1802#
1803# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
1804#
1805
1806#
1807# may also be needed; see USB_STORAGE Help for more information
1808#
1809CONFIG_USB_STORAGE=y
1810# CONFIG_USB_STORAGE_DEBUG is not set
1811CONFIG_USB_STORAGE_DATAFAB=y
1812CONFIG_USB_STORAGE_FREECOM=y
1813CONFIG_USB_STORAGE_ISD200=y
1814CONFIG_USB_STORAGE_DPCM=y
1815CONFIG_USB_STORAGE_USBAT=y
1816CONFIG_USB_STORAGE_SDDR09=y
1817CONFIG_USB_STORAGE_SDDR55=y
1818CONFIG_USB_STORAGE_JUMPSHOT=y
1819CONFIG_USB_STORAGE_ALAUDA=y
1820# CONFIG_USB_STORAGE_ONETOUCH is not set
1821CONFIG_USB_STORAGE_KARMA=y
1822# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
1823# CONFIG_USB_LIBUSUAL is not set
1824
1825#
1826# USB Imaging devices
1827#
1828CONFIG_USB_MDC800=m
1829CONFIG_USB_MICROTEK=m
1830
1831#
1832# USB port drivers
1833#
1834CONFIG_USB_SERIAL=m
1835CONFIG_USB_EZUSB=y
1836CONFIG_USB_SERIAL_GENERIC=y
1837CONFIG_USB_SERIAL_AIRCABLE=m
1838CONFIG_USB_SERIAL_ARK3116=m
1839CONFIG_USB_SERIAL_BELKIN=m
1840CONFIG_USB_SERIAL_CH341=m
1841CONFIG_USB_SERIAL_WHITEHEAT=m
1842CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m
1843CONFIG_USB_SERIAL_CP2101=m
1844CONFIG_USB_SERIAL_CYPRESS_M8=m
1845CONFIG_USB_SERIAL_EMPEG=m
1846CONFIG_USB_SERIAL_FTDI_SIO=m
1847CONFIG_USB_SERIAL_FUNSOFT=m
1848CONFIG_USB_SERIAL_VISOR=m
1849CONFIG_USB_SERIAL_IPAQ=m
1850CONFIG_USB_SERIAL_IR=m
1851CONFIG_USB_SERIAL_EDGEPORT=m
1852CONFIG_USB_SERIAL_EDGEPORT_TI=m
1853CONFIG_USB_SERIAL_GARMIN=m
1854CONFIG_USB_SERIAL_IPW=m
1855CONFIG_USB_SERIAL_IUU=m
1856CONFIG_USB_SERIAL_KEYSPAN_PDA=m
1857CONFIG_USB_SERIAL_KEYSPAN=m
1858CONFIG_USB_SERIAL_KEYSPAN_MPR=y
1859CONFIG_USB_SERIAL_KEYSPAN_USA28=y
1860CONFIG_USB_SERIAL_KEYSPAN_USA28X=y
1861CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y
1862CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y
1863CONFIG_USB_SERIAL_KEYSPAN_USA19=y
1864CONFIG_USB_SERIAL_KEYSPAN_USA18X=y
1865CONFIG_USB_SERIAL_KEYSPAN_USA19W=y
1866CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y
1867CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y
1868CONFIG_USB_SERIAL_KEYSPAN_USA49W=y
1869CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
1870CONFIG_USB_SERIAL_KLSI=m
1871CONFIG_USB_SERIAL_KOBIL_SCT=m
1872CONFIG_USB_SERIAL_MCT_U232=m
1873CONFIG_USB_SERIAL_MOS7720=m
1874CONFIG_USB_SERIAL_MOS7840=m
1875# CONFIG_USB_SERIAL_MOTOROLA is not set
1876CONFIG_USB_SERIAL_NAVMAN=m
1877CONFIG_USB_SERIAL_PL2303=m
1878CONFIG_USB_SERIAL_OTI6858=m
1879# CONFIG_USB_SERIAL_SPCP8X5 is not set
1880CONFIG_USB_SERIAL_HP4X=m
1881CONFIG_USB_SERIAL_SAFE=m
1882CONFIG_USB_SERIAL_SAFE_PADDED=y
1883CONFIG_USB_SERIAL_SIERRAWIRELESS=m
1884CONFIG_USB_SERIAL_TI=m
1885CONFIG_USB_SERIAL_CYBERJACK=m
1886CONFIG_USB_SERIAL_XIRCOM=m
1887CONFIG_USB_SERIAL_OPTION=m
1888CONFIG_USB_SERIAL_OMNINET=m
1889CONFIG_USB_SERIAL_DEBUG=m
1890
1891#
1892# USB Miscellaneous drivers
1893#
1894CONFIG_USB_EMI62=m
1895CONFIG_USB_EMI26=m
1896CONFIG_USB_ADUTUX=m
1897# CONFIG_USB_RIO500 is not set
1898CONFIG_USB_LEGOTOWER=m
1899CONFIG_USB_LCD=m
1900CONFIG_USB_BERRY_CHARGE=m
1901CONFIG_USB_LED=m
1902# CONFIG_USB_CYPRESS_CY7C63 is not set
1903# CONFIG_USB_CYTHERM is not set
1904CONFIG_USB_PHIDGET=m
1905CONFIG_USB_PHIDGETKIT=m
1906CONFIG_USB_PHIDGETMOTORCONTROL=m
1907CONFIG_USB_PHIDGETSERVO=m
1908CONFIG_USB_IDMOUSE=m
1909CONFIG_USB_FTDI_ELAN=m
1910CONFIG_USB_APPLEDISPLAY=m
1911CONFIG_USB_SISUSBVGA=m
1912CONFIG_USB_SISUSBVGA_CON=y
1913CONFIG_USB_LD=m
1914CONFIG_USB_TRANCEVIBRATOR=m
1915CONFIG_USB_IOWARRIOR=m
1916# CONFIG_USB_TEST is not set
1917# CONFIG_USB_ISIGHTFW is not set
1918# CONFIG_USB_GADGET is not set
1919CONFIG_MMC=m
1920# CONFIG_MMC_DEBUG is not set
1921# CONFIG_MMC_UNSAFE_RESUME is not set
1922
1923#
1924# MMC/SD Card Drivers
1925#
1926CONFIG_MMC_BLOCK=m
1927CONFIG_MMC_BLOCK_BOUNCE=y
1928CONFIG_SDIO_UART=m
1929# CONFIG_MMC_TEST is not set
1930
1931#
1932# MMC/SD Host Controller Drivers
1933#
1934CONFIG_MMC_SDHCI=m
1935# CONFIG_MMC_SDHCI_PCI is not set
1936CONFIG_MMC_WBSD=m
1937CONFIG_MMC_TIFM_SD=m
1938CONFIG_MEMSTICK=m
1939CONFIG_MEMSTICK_DEBUG=y
1940
1941#
1942# MemoryStick drivers
1943#
1944# CONFIG_MEMSTICK_UNSAFE_RESUME is not set
1945CONFIG_MSPRO_BLOCK=m
1946
1947#
1948# MemoryStick Host Controller Drivers
1949#
1950# CONFIG_MEMSTICK_TIFM_MS is not set
1951# CONFIG_MEMSTICK_JMICRON_38X is not set
1952CONFIG_NEW_LEDS=y
1953CONFIG_LEDS_CLASS=m
1954
1955#
1956# LED drivers
1957#
1958# CONFIG_LEDS_PCA9532 is not set
1959# CONFIG_LEDS_CLEVO_MAIL is not set
1960# CONFIG_LEDS_PCA955X is not set
1961
1962#
1963# LED Triggers
1964#
1965CONFIG_LEDS_TRIGGERS=y
1966# CONFIG_LEDS_TRIGGER_TIMER is not set
1967# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
1968# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
1969# CONFIG_ACCESSIBILITY is not set
1970# CONFIG_INFINIBAND is not set
1971# CONFIG_EDAC is not set
1972CONFIG_RTC_LIB=y
1973CONFIG_RTC_CLASS=y
1974# CONFIG_RTC_HCTOSYS is not set
1975# CONFIG_RTC_DEBUG is not set
1976
1977#
1978# RTC interfaces
1979#
1980CONFIG_RTC_INTF_SYSFS=y
1981CONFIG_RTC_INTF_PROC=y
1982CONFIG_RTC_INTF_DEV=y
1983# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
1984# CONFIG_RTC_DRV_TEST is not set
1985
1986#
1987# I2C RTC drivers
1988#
1989# CONFIG_RTC_DRV_DS1307 is not set
1990# CONFIG_RTC_DRV_DS1374 is not set
1991# CONFIG_RTC_DRV_DS1672 is not set
1992# CONFIG_RTC_DRV_MAX6900 is not set
1993# CONFIG_RTC_DRV_RS5C372 is not set
1994# CONFIG_RTC_DRV_ISL1208 is not set
1995# CONFIG_RTC_DRV_X1205 is not set
1996# CONFIG_RTC_DRV_PCF8563 is not set
1997# CONFIG_RTC_DRV_PCF8583 is not set
1998# CONFIG_RTC_DRV_M41T80 is not set
1999# CONFIG_RTC_DRV_S35390A is not set
2000# CONFIG_RTC_DRV_FM3130 is not set
2001
2002#
2003# SPI RTC drivers
2004#
2005
2006#
2007# Platform RTC drivers
2008#
2009CONFIG_RTC_DRV_CMOS=y
2010# CONFIG_RTC_DRV_DS1511 is not set
2011# CONFIG_RTC_DRV_DS1553 is not set
2012# CONFIG_RTC_DRV_DS1742 is not set
2013# CONFIG_RTC_DRV_STK17TA8 is not set
2014# CONFIG_RTC_DRV_M48T86 is not set
2015# CONFIG_RTC_DRV_M48T59 is not set
2016# CONFIG_RTC_DRV_V3020 is not set
2017
2018#
2019# on-CPU RTC drivers
2020#
2021# CONFIG_DMADEVICES is not set
2022# CONFIG_UIO is not set
2023
2024#
2025# Firmware Drivers
2026#
2027# CONFIG_EDD is not set
2028CONFIG_FIRMWARE_MEMMAP=y
2029# CONFIG_DELL_RBU is not set
2030# CONFIG_DCDBAS is not set
2031# CONFIG_DMIID is not set
2032# CONFIG_ISCSI_IBFT_FIND is not set
2033
2034#
2035# File systems
2036#
2037# CONFIG_EXT2_FS is not set
2038CONFIG_EXT3_FS=y
2039CONFIG_EXT3_FS_XATTR=y
2040CONFIG_EXT3_FS_POSIX_ACL=y
2041CONFIG_EXT3_FS_SECURITY=y
2042# CONFIG_EXT4DEV_FS is not set
2043CONFIG_JBD=y
2044# CONFIG_JBD_DEBUG is not set
2045CONFIG_FS_MBCACHE=y
2046# CONFIG_REISERFS_FS is not set
2047# CONFIG_JFS_FS is not set
2048CONFIG_FS_POSIX_ACL=y
2049# CONFIG_XFS_FS is not set
2050# CONFIG_OCFS2_FS is not set
2051CONFIG_DNOTIFY=y
2052CONFIG_INOTIFY=y
2053CONFIG_INOTIFY_USER=y
2054CONFIG_QUOTA=y
2055CONFIG_QUOTA_NETLINK_INTERFACE=y
2056# CONFIG_PRINT_QUOTA_WARNING is not set
2057# CONFIG_QFMT_V1 is not set
2058CONFIG_QFMT_V2=y
2059CONFIG_QUOTACTL=y
2060# CONFIG_AUTOFS_FS is not set
2061# CONFIG_AUTOFS4_FS is not set
2062CONFIG_FUSE_FS=m
2063CONFIG_GENERIC_ACL=y
2064
2065#
2066# CD-ROM/DVD Filesystems
2067#
2068CONFIG_ISO9660_FS=y
2069CONFIG_JOLIET=y
2070CONFIG_ZISOFS=y
2071CONFIG_UDF_FS=m
2072CONFIG_UDF_NLS=y
2073
2074#
2075# DOS/FAT/NT Filesystems
2076#
2077CONFIG_FAT_FS=y
2078CONFIG_MSDOS_FS=y
2079CONFIG_VFAT_FS=y
2080CONFIG_FAT_DEFAULT_CODEPAGE=437
2081CONFIG_FAT_DEFAULT_IOCHARSET="ascii"
2082# CONFIG_NTFS_FS is not set
2083
2084#
2085# Pseudo filesystems
2086#
2087CONFIG_PROC_FS=y
2088CONFIG_PROC_KCORE=y
2089CONFIG_PROC_VMCORE=y
2090CONFIG_PROC_SYSCTL=y
2091CONFIG_SYSFS=y
2092CONFIG_TMPFS=y
2093CONFIG_TMPFS_POSIX_ACL=y
2094CONFIG_HUGETLBFS=y
2095CONFIG_HUGETLB_PAGE=y
2096CONFIG_CONFIGFS_FS=m
2097
2098#
2099# Miscellaneous filesystems
2100#
2101# CONFIG_ADFS_FS is not set
2102# CONFIG_AFFS_FS is not set
2103# CONFIG_ECRYPT_FS is not set
2104# CONFIG_HFS_FS is not set
2105# CONFIG_HFSPLUS_FS is not set
2106# CONFIG_BEFS_FS is not set
2107# CONFIG_BFS_FS is not set
2108# CONFIG_EFS_FS is not set
2109# CONFIG_CRAMFS is not set
2110# CONFIG_VXFS_FS is not set
2111# CONFIG_MINIX_FS is not set
2112# CONFIG_OMFS_FS is not set
2113# CONFIG_HPFS_FS is not set
2114# CONFIG_QNX4FS_FS is not set
2115# CONFIG_ROMFS_FS is not set
2116# CONFIG_SYSV_FS is not set
2117# CONFIG_UFS_FS is not set
2118CONFIG_NETWORK_FILESYSTEMS=y
2119# CONFIG_NFS_FS is not set
2120# CONFIG_NFSD is not set
2121# CONFIG_SMB_FS is not set
2122# CONFIG_CIFS is not set
2123# CONFIG_NCP_FS is not set
2124# CONFIG_CODA_FS is not set
2125# CONFIG_AFS_FS is not set
2126
2127#
2128# Partition Types
2129#
2130CONFIG_PARTITION_ADVANCED=y
2131# CONFIG_ACORN_PARTITION is not set
2132CONFIG_OSF_PARTITION=y
2133CONFIG_AMIGA_PARTITION=y
2134# CONFIG_ATARI_PARTITION is not set
2135CONFIG_MAC_PARTITION=y
2136CONFIG_MSDOS_PARTITION=y
2137CONFIG_BSD_DISKLABEL=y
2138CONFIG_MINIX_SUBPARTITION=y
2139CONFIG_SOLARIS_X86_PARTITION=y
2140CONFIG_UNIXWARE_DISKLABEL=y
2141# CONFIG_LDM_PARTITION is not set
2142CONFIG_SGI_PARTITION=y
2143# CONFIG_ULTRIX_PARTITION is not set
2144CONFIG_SUN_PARTITION=y
2145CONFIG_KARMA_PARTITION=y
2146CONFIG_EFI_PARTITION=y
2147# CONFIG_SYSV68_PARTITION is not set
2148CONFIG_NLS=y
2149CONFIG_NLS_DEFAULT="utf8"
2150CONFIG_NLS_CODEPAGE_437=y
2151CONFIG_NLS_CODEPAGE_737=m
2152CONFIG_NLS_CODEPAGE_775=m
2153CONFIG_NLS_CODEPAGE_850=m
2154CONFIG_NLS_CODEPAGE_852=m
2155CONFIG_NLS_CODEPAGE_855=m
2156CONFIG_NLS_CODEPAGE_857=m
2157CONFIG_NLS_CODEPAGE_860=m
2158CONFIG_NLS_CODEPAGE_861=m
2159CONFIG_NLS_CODEPAGE_862=m
2160CONFIG_NLS_CODEPAGE_863=m
2161CONFIG_NLS_CODEPAGE_864=m
2162CONFIG_NLS_CODEPAGE_865=m
2163CONFIG_NLS_CODEPAGE_866=m
2164CONFIG_NLS_CODEPAGE_869=m
2165CONFIG_NLS_CODEPAGE_936=m
2166CONFIG_NLS_CODEPAGE_950=m
2167CONFIG_NLS_CODEPAGE_932=m
2168CONFIG_NLS_CODEPAGE_949=m
2169CONFIG_NLS_CODEPAGE_874=m
2170CONFIG_NLS_ISO8859_8=m
2171CONFIG_NLS_CODEPAGE_1250=m
2172CONFIG_NLS_CODEPAGE_1251=m
2173CONFIG_NLS_ASCII=y
2174CONFIG_NLS_ISO8859_1=m
2175CONFIG_NLS_ISO8859_2=m
2176CONFIG_NLS_ISO8859_3=m
2177CONFIG_NLS_ISO8859_4=m
2178CONFIG_NLS_ISO8859_5=m
2179CONFIG_NLS_ISO8859_6=m
2180CONFIG_NLS_ISO8859_7=m
2181CONFIG_NLS_ISO8859_9=m
2182CONFIG_NLS_ISO8859_13=m
2183CONFIG_NLS_ISO8859_14=m
2184CONFIG_NLS_ISO8859_15=m
2185CONFIG_NLS_KOI8_R=m
2186CONFIG_NLS_KOI8_U=m
2187CONFIG_NLS_UTF8=m
2188# CONFIG_DLM is not set
2189
2190#
2191# Kernel hacking
2192#
2193CONFIG_TRACE_IRQFLAGS_SUPPORT=y
2194CONFIG_PRINTK_TIME=y
2195# CONFIG_ENABLE_WARN_DEPRECATED is not set
2196CONFIG_ENABLE_MUST_CHECK=y
2197CONFIG_FRAME_WARN=1024
2198CONFIG_MAGIC_SYSRQ=y
2199CONFIG_UNUSED_SYMBOLS=y
2200CONFIG_DEBUG_FS=y
2201# CONFIG_HEADERS_CHECK is not set
2202CONFIG_DEBUG_KERNEL=y
2203CONFIG_DEBUG_SHIRQ=y
2204CONFIG_DETECT_SOFTLOCKUP=y
2205# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
2206CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
2207CONFIG_SCHED_DEBUG=y
2208CONFIG_SCHEDSTATS=y
2209CONFIG_TIMER_STATS=y
2210# CONFIG_DEBUG_OBJECTS is not set
2211# CONFIG_DEBUG_SLAB is not set
2212# CONFIG_DEBUG_RT_MUTEXES is not set
2213# CONFIG_RT_MUTEX_TESTER is not set
2214# CONFIG_DEBUG_SPINLOCK is not set
2215# CONFIG_DEBUG_MUTEXES is not set
2216# CONFIG_DEBUG_LOCK_ALLOC is not set
2217# CONFIG_PROVE_LOCKING is not set
2218# CONFIG_LOCK_STAT is not set
2219CONFIG_DEBUG_SPINLOCK_SLEEP=y
2220# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
2221CONFIG_STACKTRACE=y
2222# CONFIG_DEBUG_KOBJECT is not set
2223# CONFIG_DEBUG_HIGHMEM is not set
2224CONFIG_DEBUG_BUGVERBOSE=y
2225# CONFIG_DEBUG_INFO is not set
2226# CONFIG_DEBUG_VM is not set
2227# CONFIG_DEBUG_WRITECOUNT is not set
2228CONFIG_DEBUG_MEMORY_INIT=y
2229CONFIG_DEBUG_LIST=y
2230# CONFIG_DEBUG_SG is not set
2231CONFIG_FRAME_POINTER=y
2232CONFIG_BOOT_PRINTK_DELAY=y
2233# CONFIG_RCU_TORTURE_TEST is not set
2234# CONFIG_BACKTRACE_SELF_TEST is not set
2235# CONFIG_FAULT_INJECTION is not set
2236CONFIG_LATENCYTOP=y
2237CONFIG_SYSCTL_SYSCALL_CHECK=y
2238CONFIG_HAVE_FTRACE=y
2239CONFIG_HAVE_DYNAMIC_FTRACE=y
2240CONFIG_TRACING=y
2241# CONFIG_FTRACE is not set
2242# CONFIG_IRQSOFF_TRACER is not set
2243CONFIG_SYSPROF_TRACER=y
2244# CONFIG_SCHED_TRACER is not set
2245# CONFIG_CONTEXT_SWITCH_TRACER is not set
2246# CONFIG_FTRACE_STARTUP_TEST is not set
2247# CONFIG_PROVIDE_OHCI1394_DMA_INIT is not set
2248# CONFIG_SAMPLES is not set
2249CONFIG_HAVE_ARCH_KGDB=y
2250# CONFIG_KGDB is not set
2251# CONFIG_STRICT_DEVMEM is not set
2252CONFIG_X86_VERBOSE_BOOTUP=y
2253CONFIG_EARLY_PRINTK=y
2254# CONFIG_DEBUG_STACKOVERFLOW is not set
2255# CONFIG_DEBUG_STACK_USAGE is not set
2256# CONFIG_DEBUG_PAGEALLOC is not set
2257# CONFIG_DEBUG_PER_CPU_MAPS is not set
2258CONFIG_X86_PTDUMP=y
2259CONFIG_DEBUG_RODATA=y
2260# CONFIG_DEBUG_RODATA_TEST is not set
2261# CONFIG_DEBUG_NX_TEST is not set
2262# CONFIG_4KSTACKS is not set
2263CONFIG_DOUBLEFAULT=y
2264# CONFIG_MMIOTRACE is not set
2265CONFIG_IO_DELAY_TYPE_0X80=0
2266CONFIG_IO_DELAY_TYPE_0XED=1
2267CONFIG_IO_DELAY_TYPE_UDELAY=2
2268CONFIG_IO_DELAY_TYPE_NONE=3
2269CONFIG_IO_DELAY_0X80=y
2270# CONFIG_IO_DELAY_0XED is not set
2271# CONFIG_IO_DELAY_UDELAY is not set
2272# CONFIG_IO_DELAY_NONE is not set
2273CONFIG_DEFAULT_IO_DELAY_TYPE=0
2274CONFIG_DEBUG_BOOT_PARAMS=y
2275# CONFIG_CPA_DEBUG is not set
2276# CONFIG_OPTIMIZE_INLINING is not set
2277
2278#
2279# Security options
2280#
2281CONFIG_KEYS=y
2282CONFIG_KEYS_DEBUG_PROC_KEYS=y
2283CONFIG_SECURITY=y
2284CONFIG_SECURITY_NETWORK=y
2285CONFIG_SECURITY_NETWORK_XFRM=y
2286CONFIG_SECURITY_FILE_CAPABILITIES=y
2287# CONFIG_SECURITY_ROOTPLUG is not set
2288CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=65536
2289# CONFIG_SECURITY_SELINUX is not set
2290# CONFIG_SECURITY_SMACK is not set
2291CONFIG_CRYPTO=y
2292
2293#
2294# Crypto core or helper
2295#
2296CONFIG_CRYPTO_ALGAPI=y
2297CONFIG_CRYPTO_AEAD=m
2298CONFIG_CRYPTO_BLKCIPHER=m
2299CONFIG_CRYPTO_HASH=y
2300CONFIG_CRYPTO_MANAGER=y
2301CONFIG_CRYPTO_GF128MUL=m
2302CONFIG_CRYPTO_NULL=m
2303# CONFIG_CRYPTO_CRYPTD is not set
2304CONFIG_CRYPTO_AUTHENC=m
2305CONFIG_CRYPTO_TEST=m
2306
2307#
2308# Authenticated Encryption with Associated Data
2309#
2310CONFIG_CRYPTO_CCM=m
2311CONFIG_CRYPTO_GCM=m
2312CONFIG_CRYPTO_SEQIV=m
2313
2314#
2315# Block modes
2316#
2317CONFIG_CRYPTO_CBC=m
2318CONFIG_CRYPTO_CTR=m
2319# CONFIG_CRYPTO_CTS is not set
2320CONFIG_CRYPTO_ECB=m
2321CONFIG_CRYPTO_LRW=m
2322CONFIG_CRYPTO_PCBC=m
2323CONFIG_CRYPTO_XTS=m
2324
2325#
2326# Hash modes
2327#
2328CONFIG_CRYPTO_HMAC=y
2329CONFIG_CRYPTO_XCBC=m
2330
2331#
2332# Digest
2333#
2334CONFIG_CRYPTO_CRC32C=m
2335CONFIG_CRYPTO_MD4=m
2336CONFIG_CRYPTO_MD5=y
2337CONFIG_CRYPTO_MICHAEL_MIC=m
2338# CONFIG_CRYPTO_RMD128 is not set
2339# CONFIG_CRYPTO_RMD160 is not set
2340# CONFIG_CRYPTO_RMD256 is not set
2341# CONFIG_CRYPTO_RMD320 is not set
2342CONFIG_CRYPTO_SHA1=y
2343CONFIG_CRYPTO_SHA256=m
2344CONFIG_CRYPTO_SHA512=m
2345CONFIG_CRYPTO_TGR192=m
2346CONFIG_CRYPTO_WP512=m
2347
2348#
2349# Ciphers
2350#
2351CONFIG_CRYPTO_AES=m
2352# CONFIG_CRYPTO_AES_586 is not set
2353CONFIG_CRYPTO_ANUBIS=m
2354CONFIG_CRYPTO_ARC4=m
2355CONFIG_CRYPTO_BLOWFISH=m
2356CONFIG_CRYPTO_CAMELLIA=m
2357CONFIG_CRYPTO_CAST5=m
2358CONFIG_CRYPTO_CAST6=m
2359CONFIG_CRYPTO_DES=m
2360CONFIG_CRYPTO_FCRYPT=m
2361CONFIG_CRYPTO_KHAZAD=m
2362CONFIG_CRYPTO_SALSA20=m
2363# CONFIG_CRYPTO_SALSA20_586 is not set
2364CONFIG_CRYPTO_SEED=m
2365CONFIG_CRYPTO_SERPENT=m
2366CONFIG_CRYPTO_TEA=m
2367CONFIG_CRYPTO_TWOFISH=m
2368CONFIG_CRYPTO_TWOFISH_COMMON=m
2369# CONFIG_CRYPTO_TWOFISH_586 is not set
2370
2371#
2372# Compression
2373#
2374CONFIG_CRYPTO_DEFLATE=m
2375# CONFIG_CRYPTO_LZO is not set
2376CONFIG_CRYPTO_HW=y
2377# CONFIG_CRYPTO_DEV_PADLOCK is not set
2378# CONFIG_CRYPTO_DEV_GEODE is not set
2379# CONFIG_CRYPTO_DEV_HIFN_795X is not set
2380CONFIG_HAVE_KVM=y
2381# CONFIG_VIRTUALIZATION is not set
2382
2383#
2384# Library routines
2385#
2386CONFIG_BITREVERSE=y
2387CONFIG_GENERIC_FIND_FIRST_BIT=y
2388CONFIG_GENERIC_FIND_NEXT_BIT=y
2389CONFIG_CRC_CCITT=m
2390CONFIG_CRC16=m
2391CONFIG_CRC_T10DIF=y
2392CONFIG_CRC_ITU_T=m
2393CONFIG_CRC32=y
2394# CONFIG_CRC7 is not set
2395CONFIG_LIBCRC32C=m
2396CONFIG_AUDIT_GENERIC=y
2397CONFIG_ZLIB_INFLATE=y
2398CONFIG_ZLIB_DEFLATE=m
2399CONFIG_TEXTSEARCH=y
2400CONFIG_TEXTSEARCH_KMP=m
2401CONFIG_TEXTSEARCH_BM=m
2402CONFIG_TEXTSEARCH_FSM=m
2403CONFIG_PLIST=y
2404CONFIG_HAS_IOMEM=y
2405CONFIG_HAS_IOPORT=y
2406CONFIG_HAS_DMA=y
diff --git a/meta-moblin/packages/linux/linux-moblin.inc b/meta-moblin/packages/linux/linux-moblin.inc
new file mode 100644
index 0000000000..a7fa15124d
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin.inc
@@ -0,0 +1,18 @@
1DESCRIPTION = "2.6 Linux Development Kernel for moblin Atom based platforms"
2SECTION = "kernel"
3LICENSE = "GPL"
4
5inherit kernel
6
7do_configure() {
8
9 rm -f ${S}/.config || true
10
11 cp ${WORKDIR}/defconfig-${MACHINE} ${S}/.config
12
13 yes '' | oe_runmake oldconfig
14
15}
16
17
18COMPATIBLE_MACHINE = "netbook" \ No newline at end of file
diff --git a/meta-moblin/packages/linux/linux-moblin_2.6.27-rc1.bb b/meta-moblin/packages/linux/linux-moblin_2.6.27-rc1.bb
new file mode 100644
index 0000000000..dd46944004
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin_2.6.27-rc1.bb
@@ -0,0 +1,21 @@
1require linux-moblin.inc
2
3PR = "r5"
4
5SRC_URI = "${KERNELORG_MIRROR}pub/linux/kernel/v2.6/linux-2.6.26.tar.bz2 \
6 ${KERNELORG_MIRROR}pub/linux/kernel/v2.6/testing/patch-2.6.27-rc1.bz2;patch=1 \
7 file://0001_Export_shmem_file_setup_for_DRM-GEM.patch;patch=1 \
8 file://0002_i915.Use_more_consistent_names_for_regs.patch;patch=1 \
9 file://0003_i915.Add_support_for_MSI_and_interrupt_mitigation.patch;patch=1 \
10 file://0004_i915.Track_progress_inside_of_batchbuffers_for_determining_wedgedness.patch;patch=1 \
11 file://0005_i915.remove_settable_use_mi_batchbuffer_start.patch;patch=1 \
12 file://0006_i915.Ignore_X_server_provided_mmio_address.patch;patch=1 \
13 file://0007_i915.Initialize_hardware_status_page_at_device_load_when_possible.patch;patch=1 \
14 file://0008_drm.Add_GEM_graphics_execution_manager_to_i915_driver.patch;patch=1 \
15 file://0009-squashfs3.3-2.6.27.patch;patch=1 \
16 file://0010_unionfs-2.4_for_2.6.27-rc1.patch;patch=1 \
17 file://0011_workaround_unidef_step.patch;patch=1 \
18 file://0012_intelfb_945gme.patch;patch=1 \
19 file://defconfig-netbook"
20
21S = "${WORKDIR}/linux-2.6.26"
diff --git a/meta-moblin/packages/linux/linux-moblin_2.6.27-rc6.bb b/meta-moblin/packages/linux/linux-moblin_2.6.27-rc6.bb
new file mode 100644
index 0000000000..cdcd42cd79
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin_2.6.27-rc6.bb
@@ -0,0 +1,54 @@
1require linux-moblin.inc
2
3PR = "r4"
4
5DEFAULT_PREFERENCE = "-1"
6DEFAULT_PREFERENCE_netbook = "1"
7
8SRC_URI = "${KERNELORG_MIRROR}pub/linux/kernel/v2.6/linux-2.6.26.tar.bz2 \
9 ${KERNELORG_MIRROR}pub/linux/kernel/v2.6/testing/patch-2.6.27-rc6.bz2;patch=1 \
10 file://0001-drm-remove-define-for-non-linux-systems.patch;patch=1 \
11 file://0002-i915-remove-settable-use_mi_batchbuffer_start.patch;patch=1 \
12 file://0003-i915-Ignore-X-server-provided-mmio-address.patch;patch=1 \
13 file://0004-i915-Use-more-consistent-names-for-regs-and-store.patch;patch=1 \
14 file://0005-i915-Add-support-for-MSI-and-interrupt-mitigation.patch;patch=1 \
15 file://0006-i915-Track-progress-inside-of-batchbuffers-for-dete.patch;patch=1 \
16 file://0007-i915-Initialize-hardware-status-page-at-device-load.patch;patch=1 \
17 file://0008-Add-Intel-ACPI-IGD-OpRegion-support.patch;patch=1 \
18 file://0009-drm-fix-sysfs-error-path.patch;patch=1 \
19 file://0010-i915-separate-suspend-resume-functions.patch;patch=1 \
20 file://0011-drm-vblank-rework.patch;patch=1 \
21 file://0012-Export-shmem_file_setup-for-DRM-GEM.patch;patch=1 \
22 file://0013-Export-kmap_atomic_pfn-for-DRM-GEM.patch;patch=1 \
23 file://0014-drm-Add-GEM-graphics-execution-manager-to-i915.patch;patch=1 \
24 file://0015-i915-Add-chip-set-ID-param.patch;patch=1 \
25 file://0016-i915-Use-struct_mutex-to-protect-ring-in-GEM-mode.patch;patch=1 \
26 file://0017-i915-Make-use-of-sarea_priv-conditional.patch;patch=1 \
27 file://0018-i915-gem-install-and-uninstall-irq-handler-in-enter.patch;patch=1 \
28 file://0019-DRM-Return-EBADF-on-bad-object-in-flink-and-retur.patch;patch=1 \
29 file://0020-drm-Avoid-oops-in-GEM-execbuffers-with-bad-argument.patch;patch=1 \
30 file://0021-drm-G33-class-hardware-has-a-newer-965-style-MCH-n.patch;patch=1 \
31 file://0022-drm-use-ioremap_wc-in-i915-instead-of-ioremap.patch;patch=1 \
32 file://0023-drm-clean-up-many-sparse-warnings-in-i915.patch;patch=1 \
33 file://0024-fastboot-create-a-asynchronous-initlevel.patch;patch=1 \
34 file://0025-fastboot-turn-the-USB-hostcontroller-initcalls-into.patch;patch=1 \
35 file://0026-fastboot-convert-a-few-non-critical-ACPI-drivers-to.patch;patch=1 \
36 file://0027-fastboot-hold-the-BKL-over-the-async-init-call-sequ.patch;patch=1 \
37 file://0028-fastboot-sync-the-async-execution-before-late_initc.patch;patch=1 \
38 file://0029-fastboot-make-fastboot-a-config-option.patch;patch=1 \
39 file://0030-fastboot-retry-mounting-the-root-fs-if-we-can-t-fin.patch;patch=1 \
40 file://0031-fastboot-make-the-raid-autodetect-code-wait-for-all.patch;patch=1 \
41 file://0032-fastboot-remove-wait-for-all-devices-before-mounti.patch;patch=1 \
42 file://0033-fastboot-make-the-RAID-autostart-code-print-a-messa.patch;patch=1 \
43 file://0034-fastboot-fix-typo-in-init-Kconfig-text.patch;patch=1 \
44 file://0035-fastboot-remove-duplicate-unpack_to_rootfs.patch;patch=1 \
45 file://0036-warning-fix-init-do_mounts_md-c.patch;patch=1 \
46 file://0037-init-initramfs.c-unused-function-when-compiling-wit.patch;patch=1 \
47 file://0038-fastboot-fix-blackfin-breakage-due-to-vmlinux.lds-c.patch;patch=1 \
48 file://0039-Add-a-script-to-visualize-the-kernel-boot-process.patch;patch=1 \
49 file://0040-fastboot-fix-issues-and-improve-output-of-bootgraph.patch;patch=1 \
50 file://0041-r8169-8101e.patch;patch=1 \
51 file://0042-intelfb-945gme.patch;patch=1 \
52 file://defconfig-netbook"
53
54S = "${WORKDIR}/linux-2.6.26"
diff --git a/meta-moblin/packages/linux/linux-moblin_2.6.27.bb b/meta-moblin/packages/linux/linux-moblin_2.6.27.bb
new file mode 100644
index 0000000000..fe26cc555a
--- /dev/null
+++ b/meta-moblin/packages/linux/linux-moblin_2.6.27.bb
@@ -0,0 +1,54 @@
1require linux-moblin.inc
2
3PR = "r2"
4PE = "1"
5
6DEFAULT_PREFERENCE = "-1"
7DEFAULT_PREFERENCE_netbook = "1"
8
9SRC_URI = "${KERNELORG_MIRROR}pub/linux/kernel/v2.6/linux-2.6.27.tar.bz2 \
10 file://0001-drm-remove-define-for-non-linux-systems.patch;patch=1 \
11 file://0002-i915-remove-settable-use_mi_batchbuffer_start.patch;patch=1 \
12 file://0003-i915-Ignore-X-server-provided-mmio-address.patch;patch=1 \
13 file://0004-i915-Use-more-consistent-names-for-regs-and-store.patch;patch=1 \
14 file://0005-i915-Add-support-for-MSI-and-interrupt-mitigation.patch;patch=1 \
15 file://0006-i915-Track-progress-inside-of-batchbuffers-for-dete.patch;patch=1 \
16 file://0007-i915-Initialize-hardware-status-page-at-device-load.patch;patch=1 \
17 file://0008-Add-Intel-ACPI-IGD-OpRegion-support.patch;patch=1 \
18 file://0009-drm-fix-sysfs-error-path.patch;patch=1 \
19 file://0010-i915-separate-suspend-resume-functions.patch;patch=1 \
20 file://0011-drm-vblank-rework.patch;patch=1 \
21 file://0012-Export-shmem_file_setup-for-DRM-GEM.patch;patch=1 \
22 file://0013-Export-kmap_atomic_pfn-for-DRM-GEM.patch;patch=1 \
23 file://0014-drm-Add-GEM-graphics-execution-manager-to-i915.patch;patch=1 \
24 file://0015-i915-Add-chip-set-ID-param.patch;patch=1 \
25 file://0016-i915-Use-struct_mutex-to-protect-ring-in-GEM-mode.patch;patch=1 \
26 file://0017-i915-Make-use-of-sarea_priv-conditional.patch;patch=1 \
27 file://0018-i915-gem-install-and-uninstall-irq-handler-in-enter.patch;patch=1 \
28 file://0019-DRM-Return-EBADF-on-bad-object-in-flink-and-retur.patch;patch=1 \
29 file://0020-drm-Avoid-oops-in-GEM-execbuffers-with-bad-argument.patch;patch=1 \
30 file://0021-drm-G33-class-hardware-has-a-newer-965-style-MCH-n.patch;patch=1 \
31 file://0022-drm-use-ioremap_wc-in-i915-instead-of-ioremap.patch;patch=1 \
32 file://0023-drm-clean-up-many-sparse-warnings-in-i915.patch;patch=1 \
33 file://0024-fastboot-create-a-asynchronous-initlevel.patch;patch=1 \
34 file://0025-fastboot-turn-the-USB-hostcontroller-initcalls-into.patch;patch=1 \
35 file://0026-fastboot-convert-a-few-non-critical-ACPI-drivers-to.patch;patch=1 \
36 file://0027-fastboot-hold-the-BKL-over-the-async-init-call-sequ.patch;patch=1 \
37 file://0028-fastboot-sync-the-async-execution-before-late_initc.patch;patch=1 \
38 file://0029-fastboot-make-fastboot-a-config-option.patch;patch=1 \
39 file://0030-fastboot-retry-mounting-the-root-fs-if-we-can-t-fin.patch;patch=1 \
40 file://0031-fastboot-make-the-raid-autodetect-code-wait-for-all.patch;patch=1 \
41 file://0032-fastboot-remove-wait-for-all-devices-before-mounti.patch;patch=1 \
42 file://0033-fastboot-make-the-RAID-autostart-code-print-a-messa.patch;patch=1 \
43 file://0034-fastboot-fix-typo-in-init-Kconfig-text.patch;patch=1 \
44 file://0035-fastboot-remove-duplicate-unpack_to_rootfs.patch;patch=1 \
45 file://0036-warning-fix-init-do_mounts_md-c.patch;patch=1 \
46 file://0037-init-initramfs.c-unused-function-when-compiling-wit.patch;patch=1 \
47 file://0038-fastboot-fix-blackfin-breakage-due-to-vmlinux.lds-c.patch;patch=1 \
48 file://0039-Add-a-script-to-visualize-the-kernel-boot-process.patch;patch=1 \
49 file://0040-fastboot-fix-issues-and-improve-output-of-bootgraph.patch;patch=1 \
50 file://0041-r8169-8101e.patch;patch=1 \
51 file://0042-intelfb-945gme.patch;patch=1 \
52 file://defconfig-netbook"
53
54S = "${WORKDIR}/linux-2.6.27"