Magellan Linux

Annotation 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 - (hide annotations) (download)
Tue May 8 20:58:51 2007 UTC (17 years, 1 month 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