Contents of /trunk/xorg-old/patches-6.8.2-r10/9920_all_6.8.2-fix-write-combining.patch
Parent Directory | Revision Log
Revision 167 -
(show annotations)
(download)
Tue May 8 20:58:51 2007 UTC (17 years, 4 months ago) by niro
File size: 5007 byte(s)
Tue May 8 20:58:51 2007 UTC (17 years, 4 months 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 |