1 /*
2  *
3  * Copyright (c) 1997  Metro Link Incorporated
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in
13  * all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
19  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
20  * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21  * SOFTWARE.
22  *
23  * Except as contained in this notice, the name of the Metro Link shall not be
24  * used in advertising or otherwise to promote the sale, use or other dealings
25  * in this Software without prior written authorization from Metro Link.
26  *
27  */
28 /*
29  * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
30  *
31  * Permission is hereby granted, free of charge, to any person obtaining a
32  * copy of this software and associated documentation files (the "Software"),
33  * to deal in the Software without restriction, including without limitation
34  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
35  * and/or sell copies of the Software, and to permit persons to whom the
36  * Software is furnished to do so, subject to the following conditions:
37  *
38  * The above copyright notice and this permission notice shall be included in
39  * all copies or substantial portions of the Software.
40  *
41  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
42  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
43  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
44  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
45  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
46  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
47  * OTHER DEALINGS IN THE SOFTWARE.
48  *
49  * Except as contained in this notice, the name of the copyright holder(s)
50  * and author(s) shall not be used in advertising or otherwise to promote
51  * the sale, use or other dealings in this Software without prior written
52  * authorization from the copyright holder(s) and author(s).
53  */
54 
55 #ifdef HAVE_XORG_CONFIG_H
56 #include <xorg-config.h>
57 #endif
58 
59 #include "xf86Parser.h"
60 #include "xf86tokens.h"
61 #include "Configint.h"
62 
63 
64 static const xf86ConfigSymTabRec DeviceTab[] = {
65     {ENDSECTION, "endsection"},
66     {IDENTIFIER, "identifier"},
67     {VENDOR, "vendorname"},
68     {BOARD, "boardname"},
69     {CHIPSET, "chipset"},
70     {RAMDAC, "ramdac"},
71     {DACSPEED, "dacspeed"},
72     {CLOCKS, "clocks"},
73     {MATCHSEAT, "matchseat"},
74     {OPTION, "option"},
75     {VIDEORAM, "videoram"},
76     {BIOSBASE, "biosbase"},
77     {MEMBASE, "membase"},
78     {IOBASE, "iobase"},
79     {CLOCKCHIP, "clockchip"},
80     {CHIPID, "chipid"},
81     {CHIPREV, "chiprev"},
82     {CARD, "card"},
83     {DRIVER, "driver"},
84     {BUSID, "busid"},
85     {IRQ, "irq"},
86     {SCREEN, "screen"},
87     {-1, ""},
88 };
89 
90 #define CLEANUP xf86freeDeviceList
91 
92 XF86ConfDevicePtr
xf86parseDeviceSection(void)93 xf86parseDeviceSection(void)
94 {
95     int i;
96     int has_ident = FALSE;
97     int token;
98 
99     parsePrologue(XF86ConfDevicePtr, XF86ConfDeviceRec)
100 
101         /* Zero is a valid value for these */
102         ptr->dev_chipid = -1;
103     ptr->dev_chiprev = -1;
104     ptr->dev_irq = -1;
105     while ((token = xf86getToken(DeviceTab)) != ENDSECTION) {
106         switch (token) {
107         case COMMENT:
108             ptr->dev_comment = xf86addComment(ptr->dev_comment, xf86_lex_val.str);
109             break;
110         case IDENTIFIER:
111             if (xf86getSubToken(&(ptr->dev_comment)) != STRING)
112                 Error(QUOTE_MSG, "Identifier");
113             if (has_ident == TRUE)
114                 Error(MULTIPLE_MSG, "Identifier");
115             ptr->dev_identifier = xf86_lex_val.str;
116             has_ident = TRUE;
117             break;
118         case VENDOR:
119             if (xf86getSubToken(&(ptr->dev_comment)) != STRING)
120                 Error(QUOTE_MSG, "Vendor");
121             ptr->dev_vendor = xf86_lex_val.str;
122             break;
123         case BOARD:
124             if (xf86getSubToken(&(ptr->dev_comment)) != STRING)
125                 Error(QUOTE_MSG, "Board");
126             ptr->dev_board = xf86_lex_val.str;
127             break;
128         case CHIPSET:
129             if (xf86getSubToken(&(ptr->dev_comment)) != STRING)
130                 Error(QUOTE_MSG, "Chipset");
131             ptr->dev_chipset = xf86_lex_val.str;
132             break;
133         case CARD:
134             if (xf86getSubToken(&(ptr->dev_comment)) != STRING)
135                 Error(QUOTE_MSG, "Card");
136             ptr->dev_card = xf86_lex_val.str;
137             break;
138         case DRIVER:
139             if (xf86getSubToken(&(ptr->dev_comment)) != STRING)
140                 Error(QUOTE_MSG, "Driver");
141             ptr->dev_driver = xf86_lex_val.str;
142             break;
143         case RAMDAC:
144             if (xf86getSubToken(&(ptr->dev_comment)) != STRING)
145                 Error(QUOTE_MSG, "Ramdac");
146             ptr->dev_ramdac = xf86_lex_val.str;
147             break;
148         case DACSPEED:
149             for (i = 0; i < CONF_MAXDACSPEEDS; i++)
150                 ptr->dev_dacSpeeds[i] = 0;
151             if (xf86getSubToken(&(ptr->dev_comment)) != NUMBER) {
152                 Error(DACSPEED_MSG, CONF_MAXDACSPEEDS);
153             }
154             else {
155                 ptr->dev_dacSpeeds[0] = (int) (xf86_lex_val.realnum * 1000.0 + 0.5);
156                 for (i = 1; i < CONF_MAXDACSPEEDS; i++) {
157                     if (xf86getSubToken(&(ptr->dev_comment)) == NUMBER)
158                         ptr->dev_dacSpeeds[i] = (int)
159                             (xf86_lex_val.realnum * 1000.0 + 0.5);
160                     else {
161                         xf86unGetToken(token);
162                         break;
163                     }
164                 }
165             }
166             break;
167         case VIDEORAM:
168             if (xf86getSubToken(&(ptr->dev_comment)) != NUMBER)
169                 Error(NUMBER_MSG, "VideoRam");
170             ptr->dev_videoram = xf86_lex_val.num;
171             break;
172         case BIOSBASE:
173             if (xf86getSubToken(&(ptr->dev_comment)) != NUMBER)
174                 Error(NUMBER_MSG, "BIOSBase");
175             /* ignored */
176             break;
177         case MEMBASE:
178             if (xf86getSubToken(&(ptr->dev_comment)) != NUMBER)
179                 Error(NUMBER_MSG, "MemBase");
180             ptr->dev_mem_base = xf86_lex_val.num;
181             break;
182         case IOBASE:
183             if (xf86getSubToken(&(ptr->dev_comment)) != NUMBER)
184                 Error(NUMBER_MSG, "IOBase");
185             ptr->dev_io_base = xf86_lex_val.num;
186             break;
187         case CLOCKCHIP:
188             if (xf86getSubToken(&(ptr->dev_comment)) != STRING)
189                 Error(QUOTE_MSG, "ClockChip");
190             ptr->dev_clockchip = xf86_lex_val.str;
191             break;
192         case CHIPID:
193             if (xf86getSubToken(&(ptr->dev_comment)) != NUMBER)
194                 Error(NUMBER_MSG, "ChipID");
195             ptr->dev_chipid = xf86_lex_val.num;
196             break;
197         case CHIPREV:
198             if (xf86getSubToken(&(ptr->dev_comment)) != NUMBER)
199                 Error(NUMBER_MSG, "ChipRev");
200             ptr->dev_chiprev = xf86_lex_val.num;
201             break;
202 
203         case CLOCKS:
204             token = xf86getSubToken(&(ptr->dev_comment));
205             for (i = ptr->dev_clocks;
206                  token == NUMBER && i < CONF_MAXCLOCKS; i++) {
207                 ptr->dev_clock[i] = (int) (xf86_lex_val.realnum * 1000.0 + 0.5);
208                 token = xf86getSubToken(&(ptr->dev_comment));
209             }
210             ptr->dev_clocks = i;
211             xf86unGetToken(token);
212             break;
213         case MATCHSEAT:
214             if (xf86getSubToken(&(ptr->dev_comment)) != STRING)
215                 Error(QUOTE_MSG, "MatchSeat");
216             ptr->match_seat = xf86_lex_val.str;
217             break;
218         case OPTION:
219             ptr->dev_option_lst = xf86parseOption(ptr->dev_option_lst);
220             break;
221         case BUSID:
222             if (xf86getSubToken(&(ptr->dev_comment)) != STRING)
223                 Error(QUOTE_MSG, "BusID");
224             ptr->dev_busid = xf86_lex_val.str;
225             break;
226         case IRQ:
227             if (xf86getSubToken(&(ptr->dev_comment)) != NUMBER)
228                 Error(QUOTE_MSG, "IRQ");
229             ptr->dev_irq = xf86_lex_val.num;
230             break;
231         case SCREEN:
232             if (xf86getSubToken(&(ptr->dev_comment)) != NUMBER)
233                 Error(NUMBER_MSG, "Screen");
234             ptr->dev_screen = xf86_lex_val.num;
235             break;
236         case EOF_TOKEN:
237             Error(UNEXPECTED_EOF_MSG);
238             break;
239         default:
240             Error(INVALID_KEYWORD_MSG, xf86tokenString());
241             break;
242         }
243     }
244 
245     if (!has_ident)
246         Error(NO_IDENT_MSG);
247 
248 #ifdef DEBUG
249     printf("Device section parsed\n");
250 #endif
251 
252     return ptr;
253 }
254 
255 #undef CLEANUP
256 
257 void
xf86printDeviceSection(FILE * cf,XF86ConfDevicePtr ptr)258 xf86printDeviceSection(FILE * cf, XF86ConfDevicePtr ptr)
259 {
260     int i;
261 
262     while (ptr) {
263         fprintf(cf, "Section \"Device\"\n");
264         if (ptr->dev_comment)
265             fprintf(cf, "%s", ptr->dev_comment);
266         if (ptr->dev_identifier)
267             fprintf(cf, "\tIdentifier  \"%s\"\n", ptr->dev_identifier);
268         if (ptr->dev_driver)
269             fprintf(cf, "\tDriver      \"%s\"\n", ptr->dev_driver);
270         if (ptr->dev_vendor)
271             fprintf(cf, "\tVendorName  \"%s\"\n", ptr->dev_vendor);
272         if (ptr->dev_board)
273             fprintf(cf, "\tBoardName   \"%s\"\n", ptr->dev_board);
274         if (ptr->dev_chipset)
275             fprintf(cf, "\tChipSet     \"%s\"\n", ptr->dev_chipset);
276         if (ptr->dev_card)
277             fprintf(cf, "\tCard        \"%s\"\n", ptr->dev_card);
278         if (ptr->dev_ramdac)
279             fprintf(cf, "\tRamDac      \"%s\"\n", ptr->dev_ramdac);
280         if (ptr->dev_dacSpeeds[0] > 0) {
281             fprintf(cf, "\tDacSpeed    ");
282             for (i = 0; i < CONF_MAXDACSPEEDS && ptr->dev_dacSpeeds[i] > 0; i++)
283                 fprintf(cf, "%g ", (double) (ptr->dev_dacSpeeds[i]) / 1000.0);
284             fprintf(cf, "\n");
285         }
286         if (ptr->dev_videoram)
287             fprintf(cf, "\tVideoRam    %d\n", ptr->dev_videoram);
288         if (ptr->dev_mem_base)
289             fprintf(cf, "\tMemBase     0x%lx\n", ptr->dev_mem_base);
290         if (ptr->dev_io_base)
291             fprintf(cf, "\tIOBase      0x%lx\n", ptr->dev_io_base);
292         if (ptr->dev_clockchip)
293             fprintf(cf, "\tClockChip   \"%s\"\n", ptr->dev_clockchip);
294         if (ptr->dev_chipid != -1)
295             fprintf(cf, "\tChipId      0x%x\n", ptr->dev_chipid);
296         if (ptr->dev_chiprev != -1)
297             fprintf(cf, "\tChipRev     0x%x\n", ptr->dev_chiprev);
298 
299         xf86printOptionList(cf, ptr->dev_option_lst, 1);
300         if (ptr->dev_clocks > 0) {
301             fprintf(cf, "\tClocks      ");
302             for (i = 0; i < ptr->dev_clocks; i++)
303                 fprintf(cf, "%.1f ", (double) ptr->dev_clock[i] / 1000.0);
304             fprintf(cf, "\n");
305         }
306         if (ptr->dev_busid)
307             fprintf(cf, "\tBusID       \"%s\"\n", ptr->dev_busid);
308         if (ptr->dev_screen > 0)
309             fprintf(cf, "\tScreen      %d\n", ptr->dev_screen);
310         if (ptr->dev_irq >= 0)
311             fprintf(cf, "\tIRQ         %d\n", ptr->dev_irq);
312         fprintf(cf, "EndSection\n\n");
313         ptr = ptr->list.next;
314     }
315 }
316 
317 void
xf86freeDeviceList(XF86ConfDevicePtr ptr)318 xf86freeDeviceList(XF86ConfDevicePtr ptr)
319 {
320     XF86ConfDevicePtr prev;
321 
322     while (ptr) {
323         TestFree(ptr->dev_identifier);
324         TestFree(ptr->dev_vendor);
325         TestFree(ptr->dev_board);
326         TestFree(ptr->dev_chipset);
327         TestFree(ptr->dev_card);
328         TestFree(ptr->dev_driver);
329         TestFree(ptr->dev_ramdac);
330         TestFree(ptr->dev_clockchip);
331         TestFree(ptr->dev_comment);
332         xf86optionListFree(ptr->dev_option_lst);
333 
334         prev = ptr;
335         ptr = ptr->list.next;
336         free(prev);
337     }
338 }
339 
340 XF86ConfDevicePtr
xf86findDevice(const char * ident,XF86ConfDevicePtr p)341 xf86findDevice(const char *ident, XF86ConfDevicePtr p)
342 {
343     while (p) {
344         if (xf86nameCompare(ident, p->dev_identifier) == 0)
345             return p;
346 
347         p = p->list.next;
348     }
349     return NULL;
350 }
351