Magellan Linux

Contents of /trunk/xorg-old/patches-6.8.2-r10/9920_all_6.8.2-fix-write-combining.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 167 - (show annotations) (download)
Tue May 8 20:58:51 2007 UTC (17 years ago) by niro
File size: 5007 byte(s)
-import

1 Bugzilla #2750 (https://bugs.freedesktop.org/show_bug.cgi?id=2750)
2 Linux-only fixes:
3 Fix case where a smaller write-combining region blocks write-combining
4 setting of the whole frame buffer.
5 Fix bug in wc setting code when regions are first splitted
6 and setting of write-combining then fails.
7
8 Index: xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_video.c
9 ===================================================================
10 RCS file: /cvs/xorg/xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_video.c,v
11 retrieving revision 1.4
12 retrieving revision 1.5
13 diff -u -b -B -r1.4 -r1.5
14 --- xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_video.c 28 Jan 2005 16:12:59 -0000 1.4
15 +++ xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_video.c 23 Mar 2005 21:03:41 -0000 1.5
16 @@ -187,8 +188,8 @@
17 it. */
18
19 struct mtrr_gentry gent;
20 - char buf[20];
21 struct mtrr_wc_region *wcreturn = NULL, *wcr;
22 + int count, ret=0;
23
24 /* Linux 2.0 users should not get a warning without -verbose */
25 if (!mtrr_open(2))
26 @@ -212,23 +213,52 @@
27 wcr->sentry.type = MTRR_TYPE_WRCOMB;
28 wcr->added = FALSE;
29
30 - /* There is now a nicer ioctl-based way to do this,
31 - but it isn't in current kernels. */
32 - snprintf(buf, sizeof(buf), "disable=%u\n", gent.regnum);
33 + count = 3;
34 + while (count-- &&
35 + (ret = ioctl(mtrr_fd, MTRRIOC_KILL_ENTRY, &(wcr->sentry))) < 0);
36
37 - if (write(mtrr_fd, buf, strlen(buf)) >= 0) {
38 + if (ret >= 0) {
39 xf86DrvMsg(screenNum, from,
40 "Removed MMIO write-combining range "
41 "(0x%lx,0x%lx)\n",
42 - gent.base, gent.size);
43 + (unsigned long) gent.base, (unsigned long) gent.size);
44 wcr->next = wcreturn;
45 wcreturn = wcr;
46 + gent.regnum--;
47 } else {
48 xfree(wcr);
49 xf86DrvMsgVerb(screenNum, X_WARNING, 0,
50 "Failed to remove MMIO "
51 "write-combining range (0x%lx,0x%lx)\n",
52 - gent.base, gent.size);
53 + gent.base, (unsigned long) gent.size);
54 + }
55 + }
56 + return wcreturn;
57 +}
58 +
59 +
60 +static struct mtrr_wc_region *
61 +mtrr_remove_offending(int screenNum, unsigned long base, unsigned long size,
62 + MessageType from)
63 +{
64 + struct mtrr_gentry gent;
65 + struct mtrr_wc_region *wcreturn = NULL, **wcr;
66 +
67 + if (!mtrr_open(2))
68 + return NULL;
69 +
70 + wcr = &wcreturn;
71 + for (gent.regnum = 0;
72 + ioctl(mtrr_fd, MTRRIOC_GET_ENTRY, &gent) >= 0;) {
73 + if (gent.type == MTRR_TYPE_WRCOMB
74 + && ((gent.base >= base && gent.base + gent.size < base + size) ||
75 + (gent.base > base && gent.base + gent.size <= base + size))) {
76 + *wcr = mtrr_cull_wc_region(screenNum, gent.base, gent.size, from);
77 + while(*wcr) {
78 + wcr = &((*wcr)->next);
79 + }
80 + } else {
81 + gent.regnum++;
82 }
83 }
84 return wcreturn;
85 @@ -239,7 +269,17 @@
86 mtrr_add_wc_region(int screenNum, unsigned long base, unsigned long size,
87 MessageType from)
88 {
89 - struct mtrr_wc_region *wcr;
90 + struct mtrr_wc_region **wcr, *wcreturn, *curwcr;
91 +
92 + /*
93 + * There can be only one....
94 + */
95 +
96 + wcreturn = mtrr_remove_offending(screenNum, base, size, from);
97 + wcr = &wcreturn;
98 + while (*wcr) {
99 + wcr = &((*wcr)->next);
100 + }
101
102 /* Linux 2.0 should not warn, unless the user explicitly asks for
103 WC. */
104 @@ -243,18 +283,19 @@
105
106 /* Linux 2.0 should not warn, unless the user explicitly asks for
107 WC. */
108 +
109 if (!mtrr_open(from == X_CONFIG ? 0 : 2))
110 - return NULL;
111 + return wcreturn;
112
113 - wcr = xalloc(sizeof(*wcr));
114 - if (!wcr)
115 - return NULL;
116 + *wcr = curwcr = xalloc(sizeof(**wcr));
117 + if (!curwcr)
118 + return wcreturn;
119
120 - wcr->sentry.base = base;
121 - wcr->sentry.size = size;
122 - wcr->sentry.type = MTRR_TYPE_WRCOMB;
123 - wcr->added = TRUE;
124 - wcr->next = NULL;
125 + curwcr->sentry.base = base;
126 + curwcr->sentry.size = size;
127 + curwcr->sentry.type = MTRR_TYPE_WRCOMB;
128 + curwcr->added = TRUE;
129 + curwcr->next = NULL;
130
131 #if SPLIT_WC_REGIONS
132 /*
133 @@ -279,25 +320,26 @@
134 if (n_size) {
135 xf86DrvMsgVerb(screenNum,X_INFO,3,"Splitting WC range: "
136 "base: 0x%lx, size: 0x%lx\n",base,size);
137 - wcr->next = mtrr_add_wc_region(screenNum, n_base, n_size,from);
138 + curwcr->next = mtrr_add_wc_region(screenNum, n_base, n_size,from);
139 }
140 - wcr->sentry.size = d_size;
141 + curwcr->sentry.size = d_size;
142 }
143
144 /*****************************************************************/
145 #endif /* SPLIT_WC_REGIONS */
146
147 - if (ioctl(mtrr_fd, MTRRIOC_ADD_ENTRY, &wcr->sentry) >= 0) {
148 + if (ioctl(mtrr_fd, MTRRIOC_ADD_ENTRY, &curwcr->sentry) >= 0) {
149 /* Avoid printing on every VT switch */
150 if (xf86ServerIsInitialising()) {
151 xf86DrvMsg(screenNum, from,
152 "Write-combining range (0x%lx,0x%lx)\n",
153 base, size);
154 }
155 - return wcr;
156 + return wcreturn;
157 }
158 else {
159 - xfree(wcr);
160 + *wcr = curwcr->next;
161 + xfree(curwcr);
162
163 /* Don't complain about the VGA region: MTRR fixed
164 regions aren't currently supported, but might be in
165 @@ -307,7 +349,7 @@
166 "Failed to set up write-combining range "
167 "(0x%lx,0x%lx)\n", base, size);
168 }
169 - return NULL;
170 + return wcreturn;
171 }
172 }
173