Annotation of /trunk/xorg-old/patches-6.8.2-r10/9920_all_6.8.2-fix-write-combining.patch
Parent Directory | Revision Log
Revision 167 -
(hide 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 | niro | 167 | 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 |