1f7df2e56Smrg/*
2f7df2e56Smrg *
305b261ecSmrg * Copyright (c) 1997  Metro Link Incorporated
4f7df2e56Smrg *
505b261ecSmrg * Permission is hereby granted, free of charge, to any person obtaining a
6f7df2e56Smrg * copy of this software and associated documentation files (the "Software"),
705b261ecSmrg * to deal in the Software without restriction, including without limitation
805b261ecSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
905b261ecSmrg * and/or sell copies of the Software, and to permit persons to whom the
1005b261ecSmrg * Software is furnished to do so, subject to the following conditions:
11f7df2e56Smrg *
1205b261ecSmrg * The above copyright notice and this permission notice shall be included in
1305b261ecSmrg * all copies or substantial portions of the Software.
14f7df2e56Smrg *
1505b261ecSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1605b261ecSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1705b261ecSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
1805b261ecSmrg * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
1905b261ecSmrg * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
2005b261ecSmrg * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2105b261ecSmrg * SOFTWARE.
22f7df2e56Smrg *
2305b261ecSmrg * Except as contained in this notice, the name of the Metro Link shall not be
2405b261ecSmrg * used in advertising or otherwise to promote the sale, use or other dealings
2505b261ecSmrg * in this Software without prior written authorization from Metro Link.
26f7df2e56Smrg *
2705b261ecSmrg */
2805b261ecSmrg/*
2905b261ecSmrg * Copyright (c) 1997-2003 by The XFree86 Project, Inc.
3005b261ecSmrg *
3105b261ecSmrg * Permission is hereby granted, free of charge, to any person obtaining a
3205b261ecSmrg * copy of this software and associated documentation files (the "Software"),
3305b261ecSmrg * to deal in the Software without restriction, including without limitation
3405b261ecSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
3505b261ecSmrg * and/or sell copies of the Software, and to permit persons to whom the
3605b261ecSmrg * Software is furnished to do so, subject to the following conditions:
3705b261ecSmrg *
3805b261ecSmrg * The above copyright notice and this permission notice shall be included in
3905b261ecSmrg * all copies or substantial portions of the Software.
4005b261ecSmrg *
4105b261ecSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
4205b261ecSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
4305b261ecSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
4405b261ecSmrg * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
4505b261ecSmrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
4605b261ecSmrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
4705b261ecSmrg * OTHER DEALINGS IN THE SOFTWARE.
4805b261ecSmrg *
4905b261ecSmrg * Except as contained in this notice, the name of the copyright holder(s)
5005b261ecSmrg * and author(s) shall not be used in advertising or otherwise to promote
5105b261ecSmrg * the sale, use or other dealings in this Software without prior written
5205b261ecSmrg * authorization from the copyright holder(s) and author(s).
5305b261ecSmrg */
5405b261ecSmrg
5505b261ecSmrg#ifdef HAVE_XORG_CONFIG_H
5605b261ecSmrg#include <xorg-config.h>
5705b261ecSmrg#endif
5805b261ecSmrg
5905b261ecSmrg#include "xf86Parser.h"
6005b261ecSmrg#include "xf86tokens.h"
6105b261ecSmrg#include "Configint.h"
6205b261ecSmrg
6305b261ecSmrg
647e31ba66Smrgstatic const xf86ConfigSymTabRec DeviceTab[] = {
65f7df2e56Smrg    {ENDSECTION, "endsection"},
66f7df2e56Smrg    {IDENTIFIER, "identifier"},
67f7df2e56Smrg    {VENDOR, "vendorname"},
68f7df2e56Smrg    {BOARD, "boardname"},
69f7df2e56Smrg    {CHIPSET, "chipset"},
70f7df2e56Smrg    {RAMDAC, "ramdac"},
71f7df2e56Smrg    {DACSPEED, "dacspeed"},
72f7df2e56Smrg    {CLOCKS, "clocks"},
73f7df2e56Smrg    {MATCHSEAT, "matchseat"},
74f7df2e56Smrg    {OPTION, "option"},
75f7df2e56Smrg    {VIDEORAM, "videoram"},
76f7df2e56Smrg    {BIOSBASE, "biosbase"},
77f7df2e56Smrg    {MEMBASE, "membase"},
78f7df2e56Smrg    {IOBASE, "iobase"},
79f7df2e56Smrg    {CLOCKCHIP, "clockchip"},
80f7df2e56Smrg    {CHIPID, "chipid"},
81f7df2e56Smrg    {CHIPREV, "chiprev"},
82f7df2e56Smrg    {CARD, "card"},
83f7df2e56Smrg    {DRIVER, "driver"},
84f7df2e56Smrg    {BUSID, "busid"},
85f7df2e56Smrg    {IRQ, "irq"},
86f7df2e56Smrg    {SCREEN, "screen"},
87f7df2e56Smrg    {-1, ""},
8805b261ecSmrg};
8905b261ecSmrg
9005b261ecSmrg#define CLEANUP xf86freeDeviceList
9105b261ecSmrg
9205b261ecSmrgXF86ConfDevicePtr
93f7df2e56Smrgxf86parseDeviceSection(void)
9405b261ecSmrg{
95f7df2e56Smrg    int i;
96f7df2e56Smrg    int has_ident = FALSE;
97f7df2e56Smrg    int token;
9805b261ecSmrg
99f7df2e56Smrg    parsePrologue(XF86ConfDevicePtr, XF86ConfDeviceRec)
10005b261ecSmrg
101f7df2e56Smrg        /* Zero is a valid value for these */
102f7df2e56Smrg        ptr->dev_chipid = -1;
103f7df2e56Smrg    ptr->dev_chiprev = -1;
104f7df2e56Smrg    ptr->dev_irq = -1;
105f7df2e56Smrg    while ((token = xf86getToken(DeviceTab)) != ENDSECTION) {
106f7df2e56Smrg        switch (token) {
107f7df2e56Smrg        case COMMENT:
108f7df2e56Smrg            ptr->dev_comment = xf86addComment(ptr->dev_comment, xf86_lex_val.str);
10959ca590cSmrg            free(xf86_lex_val.str);
11059ca590cSmrg            xf86_lex_val.str = NULL;
111f7df2e56Smrg            break;
112f7df2e56Smrg        case IDENTIFIER:
113f7df2e56Smrg            if (xf86getSubToken(&(ptr->dev_comment)) != STRING)
114f7df2e56Smrg                Error(QUOTE_MSG, "Identifier");
115f7df2e56Smrg            if (has_ident == TRUE)
116f7df2e56Smrg                Error(MULTIPLE_MSG, "Identifier");
117f7df2e56Smrg            ptr->dev_identifier = xf86_lex_val.str;
118f7df2e56Smrg            has_ident = TRUE;
119f7df2e56Smrg            break;
120f7df2e56Smrg        case VENDOR:
121f7df2e56Smrg            if (xf86getSubToken(&(ptr->dev_comment)) != STRING)
122f7df2e56Smrg                Error(QUOTE_MSG, "Vendor");
123f7df2e56Smrg            ptr->dev_vendor = xf86_lex_val.str;
124f7df2e56Smrg            break;
125f7df2e56Smrg        case BOARD:
126f7df2e56Smrg            if (xf86getSubToken(&(ptr->dev_comment)) != STRING)
127f7df2e56Smrg                Error(QUOTE_MSG, "Board");
128f7df2e56Smrg            ptr->dev_board = xf86_lex_val.str;
129f7df2e56Smrg            break;
130f7df2e56Smrg        case CHIPSET:
131f7df2e56Smrg            if (xf86getSubToken(&(ptr->dev_comment)) != STRING)
132f7df2e56Smrg                Error(QUOTE_MSG, "Chipset");
133f7df2e56Smrg            ptr->dev_chipset = xf86_lex_val.str;
134f7df2e56Smrg            break;
135f7df2e56Smrg        case CARD:
136f7df2e56Smrg            if (xf86getSubToken(&(ptr->dev_comment)) != STRING)
137f7df2e56Smrg                Error(QUOTE_MSG, "Card");
138f7df2e56Smrg            ptr->dev_card = xf86_lex_val.str;
139f7df2e56Smrg            break;
140f7df2e56Smrg        case DRIVER:
141f7df2e56Smrg            if (xf86getSubToken(&(ptr->dev_comment)) != STRING)
142f7df2e56Smrg                Error(QUOTE_MSG, "Driver");
143f7df2e56Smrg            ptr->dev_driver = xf86_lex_val.str;
144f7df2e56Smrg            break;
145f7df2e56Smrg        case RAMDAC:
146f7df2e56Smrg            if (xf86getSubToken(&(ptr->dev_comment)) != STRING)
147f7df2e56Smrg                Error(QUOTE_MSG, "Ramdac");
148f7df2e56Smrg            ptr->dev_ramdac = xf86_lex_val.str;
149f7df2e56Smrg            break;
150f7df2e56Smrg        case DACSPEED:
151f7df2e56Smrg            for (i = 0; i < CONF_MAXDACSPEEDS; i++)
152f7df2e56Smrg                ptr->dev_dacSpeeds[i] = 0;
153f7df2e56Smrg            if (xf86getSubToken(&(ptr->dev_comment)) != NUMBER) {
154f7df2e56Smrg                Error(DACSPEED_MSG, CONF_MAXDACSPEEDS);
155f7df2e56Smrg            }
156f7df2e56Smrg            else {
157f7df2e56Smrg                ptr->dev_dacSpeeds[0] = (int) (xf86_lex_val.realnum * 1000.0 + 0.5);
158f7df2e56Smrg                for (i = 1; i < CONF_MAXDACSPEEDS; i++) {
159f7df2e56Smrg                    if (xf86getSubToken(&(ptr->dev_comment)) == NUMBER)
160f7df2e56Smrg                        ptr->dev_dacSpeeds[i] = (int)
161f7df2e56Smrg                            (xf86_lex_val.realnum * 1000.0 + 0.5);
162f7df2e56Smrg                    else {
163f7df2e56Smrg                        xf86unGetToken(token);
164f7df2e56Smrg                        break;
165f7df2e56Smrg                    }
166f7df2e56Smrg                }
167f7df2e56Smrg            }
168f7df2e56Smrg            break;
169f7df2e56Smrg        case VIDEORAM:
170f7df2e56Smrg            if (xf86getSubToken(&(ptr->dev_comment)) != NUMBER)
171f7df2e56Smrg                Error(NUMBER_MSG, "VideoRam");
172f7df2e56Smrg            ptr->dev_videoram = xf86_lex_val.num;
173f7df2e56Smrg            break;
174f7df2e56Smrg        case BIOSBASE:
175f7df2e56Smrg            if (xf86getSubToken(&(ptr->dev_comment)) != NUMBER)
176f7df2e56Smrg                Error(NUMBER_MSG, "BIOSBase");
1777e31ba66Smrg            /* ignored */
178f7df2e56Smrg            break;
179f7df2e56Smrg        case MEMBASE:
180f7df2e56Smrg            if (xf86getSubToken(&(ptr->dev_comment)) != NUMBER)
181f7df2e56Smrg                Error(NUMBER_MSG, "MemBase");
182f7df2e56Smrg            ptr->dev_mem_base = xf86_lex_val.num;
183f7df2e56Smrg            break;
184f7df2e56Smrg        case IOBASE:
185f7df2e56Smrg            if (xf86getSubToken(&(ptr->dev_comment)) != NUMBER)
186f7df2e56Smrg                Error(NUMBER_MSG, "IOBase");
187f7df2e56Smrg            ptr->dev_io_base = xf86_lex_val.num;
188f7df2e56Smrg            break;
189f7df2e56Smrg        case CLOCKCHIP:
190f7df2e56Smrg            if (xf86getSubToken(&(ptr->dev_comment)) != STRING)
191f7df2e56Smrg                Error(QUOTE_MSG, "ClockChip");
192f7df2e56Smrg            ptr->dev_clockchip = xf86_lex_val.str;
193f7df2e56Smrg            break;
194f7df2e56Smrg        case CHIPID:
195f7df2e56Smrg            if (xf86getSubToken(&(ptr->dev_comment)) != NUMBER)
196f7df2e56Smrg                Error(NUMBER_MSG, "ChipID");
197f7df2e56Smrg            ptr->dev_chipid = xf86_lex_val.num;
198f7df2e56Smrg            break;
199f7df2e56Smrg        case CHIPREV:
200f7df2e56Smrg            if (xf86getSubToken(&(ptr->dev_comment)) != NUMBER)
201f7df2e56Smrg                Error(NUMBER_MSG, "ChipRev");
202f7df2e56Smrg            ptr->dev_chiprev = xf86_lex_val.num;
203f7df2e56Smrg            break;
204f7df2e56Smrg
205f7df2e56Smrg        case CLOCKS:
206f7df2e56Smrg            token = xf86getSubToken(&(ptr->dev_comment));
207f7df2e56Smrg            for (i = ptr->dev_clocks;
208f7df2e56Smrg                 token == NUMBER && i < CONF_MAXCLOCKS; i++) {
209f7df2e56Smrg                ptr->dev_clock[i] = (int) (xf86_lex_val.realnum * 1000.0 + 0.5);
210f7df2e56Smrg                token = xf86getSubToken(&(ptr->dev_comment));
211f7df2e56Smrg            }
212f7df2e56Smrg            ptr->dev_clocks = i;
213f7df2e56Smrg            xf86unGetToken(token);
214f7df2e56Smrg            break;
215f7df2e56Smrg        case MATCHSEAT:
216f7df2e56Smrg            if (xf86getSubToken(&(ptr->dev_comment)) != STRING)
217f7df2e56Smrg                Error(QUOTE_MSG, "MatchSeat");
218f7df2e56Smrg            ptr->match_seat = xf86_lex_val.str;
219f7df2e56Smrg            break;
220f7df2e56Smrg        case OPTION:
221f7df2e56Smrg            ptr->dev_option_lst = xf86parseOption(ptr->dev_option_lst);
222f7df2e56Smrg            break;
223f7df2e56Smrg        case BUSID:
224f7df2e56Smrg            if (xf86getSubToken(&(ptr->dev_comment)) != STRING)
225f7df2e56Smrg                Error(QUOTE_MSG, "BusID");
226f7df2e56Smrg            ptr->dev_busid = xf86_lex_val.str;
227f7df2e56Smrg            break;
228f7df2e56Smrg        case IRQ:
229f7df2e56Smrg            if (xf86getSubToken(&(ptr->dev_comment)) != NUMBER)
230f7df2e56Smrg                Error(QUOTE_MSG, "IRQ");
231f7df2e56Smrg            ptr->dev_irq = xf86_lex_val.num;
232f7df2e56Smrg            break;
233f7df2e56Smrg        case SCREEN:
234f7df2e56Smrg            if (xf86getSubToken(&(ptr->dev_comment)) != NUMBER)
235f7df2e56Smrg                Error(NUMBER_MSG, "Screen");
236f7df2e56Smrg            ptr->dev_screen = xf86_lex_val.num;
237f7df2e56Smrg            break;
238f7df2e56Smrg        case EOF_TOKEN:
239f7df2e56Smrg            Error(UNEXPECTED_EOF_MSG);
240f7df2e56Smrg            break;
241f7df2e56Smrg        default:
242f7df2e56Smrg            Error(INVALID_KEYWORD_MSG, xf86tokenString());
243f7df2e56Smrg            break;
244f7df2e56Smrg        }
245f7df2e56Smrg    }
24605b261ecSmrg
247f7df2e56Smrg    if (!has_ident)
248f7df2e56Smrg        Error(NO_IDENT_MSG);
24905b261ecSmrg
25005b261ecSmrg#ifdef DEBUG
251f7df2e56Smrg    printf("Device section parsed\n");
25205b261ecSmrg#endif
25305b261ecSmrg
254f7df2e56Smrg    return ptr;
25505b261ecSmrg}
25605b261ecSmrg
25705b261ecSmrg#undef CLEANUP
25805b261ecSmrg
25905b261ecSmrgvoid
260f7df2e56Smrgxf86printDeviceSection(FILE * cf, XF86ConfDevicePtr ptr)
26105b261ecSmrg{
262f7df2e56Smrg    int i;
26305b261ecSmrg
264f7df2e56Smrg    while (ptr) {
265f7df2e56Smrg        fprintf(cf, "Section \"Device\"\n");
266f7df2e56Smrg        if (ptr->dev_comment)
267f7df2e56Smrg            fprintf(cf, "%s", ptr->dev_comment);
268f7df2e56Smrg        if (ptr->dev_identifier)
269f7df2e56Smrg            fprintf(cf, "\tIdentifier  \"%s\"\n", ptr->dev_identifier);
270f7df2e56Smrg        if (ptr->dev_driver)
271f7df2e56Smrg            fprintf(cf, "\tDriver      \"%s\"\n", ptr->dev_driver);
272f7df2e56Smrg        if (ptr->dev_vendor)
273f7df2e56Smrg            fprintf(cf, "\tVendorName  \"%s\"\n", ptr->dev_vendor);
274f7df2e56Smrg        if (ptr->dev_board)
275f7df2e56Smrg            fprintf(cf, "\tBoardName   \"%s\"\n", ptr->dev_board);
276f7df2e56Smrg        if (ptr->dev_chipset)
277f7df2e56Smrg            fprintf(cf, "\tChipSet     \"%s\"\n", ptr->dev_chipset);
278f7df2e56Smrg        if (ptr->dev_card)
279f7df2e56Smrg            fprintf(cf, "\tCard        \"%s\"\n", ptr->dev_card);
280f7df2e56Smrg        if (ptr->dev_ramdac)
281f7df2e56Smrg            fprintf(cf, "\tRamDac      \"%s\"\n", ptr->dev_ramdac);
282f7df2e56Smrg        if (ptr->dev_dacSpeeds[0] > 0) {
283f7df2e56Smrg            fprintf(cf, "\tDacSpeed    ");
284f7df2e56Smrg            for (i = 0; i < CONF_MAXDACSPEEDS && ptr->dev_dacSpeeds[i] > 0; i++)
285f7df2e56Smrg                fprintf(cf, "%g ", (double) (ptr->dev_dacSpeeds[i]) / 1000.0);
286f7df2e56Smrg            fprintf(cf, "\n");
287f7df2e56Smrg        }
288f7df2e56Smrg        if (ptr->dev_videoram)
289f7df2e56Smrg            fprintf(cf, "\tVideoRam    %d\n", ptr->dev_videoram);
290f7df2e56Smrg        if (ptr->dev_mem_base)
291f7df2e56Smrg            fprintf(cf, "\tMemBase     0x%lx\n", ptr->dev_mem_base);
292f7df2e56Smrg        if (ptr->dev_io_base)
293f7df2e56Smrg            fprintf(cf, "\tIOBase      0x%lx\n", ptr->dev_io_base);
294f7df2e56Smrg        if (ptr->dev_clockchip)
295f7df2e56Smrg            fprintf(cf, "\tClockChip   \"%s\"\n", ptr->dev_clockchip);
296f7df2e56Smrg        if (ptr->dev_chipid != -1)
297f7df2e56Smrg            fprintf(cf, "\tChipId      0x%x\n", ptr->dev_chipid);
298f7df2e56Smrg        if (ptr->dev_chiprev != -1)
299f7df2e56Smrg            fprintf(cf, "\tChipRev     0x%x\n", ptr->dev_chiprev);
30005b261ecSmrg
301f7df2e56Smrg        xf86printOptionList(cf, ptr->dev_option_lst, 1);
302f7df2e56Smrg        if (ptr->dev_clocks > 0) {
303f7df2e56Smrg            fprintf(cf, "\tClocks      ");
304f7df2e56Smrg            for (i = 0; i < ptr->dev_clocks; i++)
305f7df2e56Smrg                fprintf(cf, "%.1f ", (double) ptr->dev_clock[i] / 1000.0);
306f7df2e56Smrg            fprintf(cf, "\n");
307f7df2e56Smrg        }
308f7df2e56Smrg        if (ptr->dev_busid)
309f7df2e56Smrg            fprintf(cf, "\tBusID       \"%s\"\n", ptr->dev_busid);
310f7df2e56Smrg        if (ptr->dev_screen > 0)
311f7df2e56Smrg            fprintf(cf, "\tScreen      %d\n", ptr->dev_screen);
312f7df2e56Smrg        if (ptr->dev_irq >= 0)
313f7df2e56Smrg            fprintf(cf, "\tIRQ         %d\n", ptr->dev_irq);
314f7df2e56Smrg        fprintf(cf, "EndSection\n\n");
315f7df2e56Smrg        ptr = ptr->list.next;
316f7df2e56Smrg    }
31705b261ecSmrg}
31805b261ecSmrg
31905b261ecSmrgvoid
320f7df2e56Smrgxf86freeDeviceList(XF86ConfDevicePtr ptr)
32105b261ecSmrg{
322f7df2e56Smrg    XF86ConfDevicePtr prev;
32305b261ecSmrg
324f7df2e56Smrg    while (ptr) {
325f7df2e56Smrg        TestFree(ptr->dev_identifier);
326f7df2e56Smrg        TestFree(ptr->dev_vendor);
327f7df2e56Smrg        TestFree(ptr->dev_board);
328f7df2e56Smrg        TestFree(ptr->dev_chipset);
329f7df2e56Smrg        TestFree(ptr->dev_card);
330f7df2e56Smrg        TestFree(ptr->dev_driver);
331f7df2e56Smrg        TestFree(ptr->dev_ramdac);
332f7df2e56Smrg        TestFree(ptr->dev_clockchip);
333f7df2e56Smrg        TestFree(ptr->dev_comment);
334f7df2e56Smrg        xf86optionListFree(ptr->dev_option_lst);
33505b261ecSmrg
336f7df2e56Smrg        prev = ptr;
337f7df2e56Smrg        ptr = ptr->list.next;
338f7df2e56Smrg        free(prev);
339f7df2e56Smrg    }
34005b261ecSmrg}
34105b261ecSmrg
34205b261ecSmrgXF86ConfDevicePtr
343f7df2e56Smrgxf86findDevice(const char *ident, XF86ConfDevicePtr p)
34405b261ecSmrg{
345f7df2e56Smrg    while (p) {
346f7df2e56Smrg        if (xf86nameCompare(ident, p->dev_identifier) == 0)
347f7df2e56Smrg            return p;
34805b261ecSmrg
349f7df2e56Smrg        p = p->list.next;
350f7df2e56Smrg    }
351f7df2e56Smrg    return NULL;
35205b261ecSmrg}
35323e2f35bSjmcneill
35423e2f35bSjmcneillXF86ConfDevicePtr
35523e2f35bSjmcneillxf86findDeviceByDriver (const char *driver, XF86ConfDevicePtr p)
35623e2f35bSjmcneill{
35723e2f35bSjmcneill	while (p)
35823e2f35bSjmcneill	{
35923e2f35bSjmcneill		if (xf86nameCompare (driver, p->dev_driver) == 0)
36023e2f35bSjmcneill			return p;
36123e2f35bSjmcneill
36223e2f35bSjmcneill		p = p->list.next;
36323e2f35bSjmcneill	}
36423e2f35bSjmcneill	return NULL;
36523e2f35bSjmcneill}
366