1219b2ee8SDavid du Colombier #include <u.h>
2219b2ee8SDavid du Colombier #include <libc.h>
3219b2ee8SDavid du Colombier #include <bio.h>
4219b2ee8SDavid du Colombier #include <ndb.h>
5219b2ee8SDavid du Colombier
69a747e4fSDavid du Colombier #include "pci.h"
7219b2ee8SDavid du Colombier #include "vga.h"
8219b2ee8SDavid du Colombier
9219b2ee8SDavid du Colombier static Ndb*
dbopen(char * dbname)10219b2ee8SDavid du Colombier dbopen(char* dbname)
11219b2ee8SDavid du Colombier {
12219b2ee8SDavid du Colombier Ndb *db;
13219b2ee8SDavid du Colombier
14219b2ee8SDavid du Colombier if((db = ndbopen(dbname)) == 0)
15219b2ee8SDavid du Colombier error("dbopen: %s: %r\n", dbname);
16219b2ee8SDavid du Colombier return db;
17219b2ee8SDavid du Colombier }
18219b2ee8SDavid du Colombier
197dd7cddfSDavid du Colombier static void
addattr(Attr ** app,Ndbtuple * t)207dd7cddfSDavid du Colombier addattr(Attr** app, Ndbtuple* t)
217dd7cddfSDavid du Colombier {
227dd7cddfSDavid du Colombier Attr *attr, *l;
237dd7cddfSDavid du Colombier
247dd7cddfSDavid du Colombier attr = alloc(sizeof(Attr));
257dd7cddfSDavid du Colombier attr->attr = alloc(strlen(t->attr)+1);
267dd7cddfSDavid du Colombier strcpy(attr->attr, t->attr);
277dd7cddfSDavid du Colombier attr->val = alloc(strlen(t->val)+1);
287dd7cddfSDavid du Colombier strcpy(attr->val, t->val);
297dd7cddfSDavid du Colombier
307dd7cddfSDavid du Colombier for(l = *app; l; l = l->next)
317dd7cddfSDavid du Colombier app = &l->next;
327dd7cddfSDavid du Colombier *app = attr;
337dd7cddfSDavid du Colombier }
347dd7cddfSDavid du Colombier
357dd7cddfSDavid du Colombier char*
dbattr(Attr * ap,char * attr)367dd7cddfSDavid du Colombier dbattr(Attr* ap, char* attr)
377dd7cddfSDavid du Colombier {
387dd7cddfSDavid du Colombier while(ap){
397dd7cddfSDavid du Colombier if(strcmp(ap->attr, attr) == 0)
407dd7cddfSDavid du Colombier return ap->val;
417dd7cddfSDavid du Colombier ap = ap->next;
427dd7cddfSDavid du Colombier }
437dd7cddfSDavid du Colombier
447dd7cddfSDavid du Colombier return 0;
457dd7cddfSDavid du Colombier }
467dd7cddfSDavid du Colombier
47219b2ee8SDavid du Colombier static Ctlr*
addctlr(Vga * vga,char * val)48219b2ee8SDavid du Colombier addctlr(Vga* vga, char* val)
49219b2ee8SDavid du Colombier {
50219b2ee8SDavid du Colombier Ctlr **ctlr;
519a747e4fSDavid du Colombier char name[Namelen+1], *p;
52219b2ee8SDavid du Colombier int i;
53219b2ee8SDavid du Colombier
54219b2ee8SDavid du Colombier /*
55219b2ee8SDavid du Colombier * A controller name may have an extension on the end
56219b2ee8SDavid du Colombier * following a '-' which can be used as a speed grade or
57219b2ee8SDavid du Colombier * subtype. Do the match without the extension.
58219b2ee8SDavid du Colombier * The linked copy of the controller struct gets the
59219b2ee8SDavid du Colombier * full name with extension.
60219b2ee8SDavid du Colombier */
619a747e4fSDavid du Colombier strncpy(name, val, Namelen);
629a747e4fSDavid du Colombier name[Namelen] = 0;
63219b2ee8SDavid du Colombier if(p = strchr(name, '-'))
64219b2ee8SDavid du Colombier *p = 0;
65219b2ee8SDavid du Colombier
66219b2ee8SDavid du Colombier for(i = 0; ctlrs[i]; i++){
67219b2ee8SDavid du Colombier if(strcmp(ctlrs[i]->name, name))
68219b2ee8SDavid du Colombier continue;
69219b2ee8SDavid du Colombier for(ctlr = &vga->link; *ctlr; ctlr = &((*ctlr)->link))
70219b2ee8SDavid du Colombier ;
71219b2ee8SDavid du Colombier *ctlr = alloc(sizeof(Ctlr));
72219b2ee8SDavid du Colombier **ctlr = *ctlrs[i];
739a747e4fSDavid du Colombier strncpy((*ctlr)->name, val, Namelen);
74219b2ee8SDavid du Colombier return *ctlr;
75219b2ee8SDavid du Colombier }
76219b2ee8SDavid du Colombier
77*b0dcc5a8SDavid du Colombier fprint(2, "dbctlr: unknown controller \"%s\" ctlr\n", val);
78219b2ee8SDavid du Colombier return 0;
79219b2ee8SDavid du Colombier }
80219b2ee8SDavid du Colombier
81219b2ee8SDavid du Colombier int
dbbios(Vga * vga,Ndbtuple * tuple)829a747e4fSDavid du Colombier dbbios(Vga *vga, Ndbtuple *tuple)
83219b2ee8SDavid du Colombier {
847dd7cddfSDavid du Colombier char *bios, *p, *string;
85219b2ee8SDavid du Colombier int len;
869a747e4fSDavid du Colombier long offset, offset1;
879a747e4fSDavid du Colombier Ndbtuple *t;
88219b2ee8SDavid du Colombier
89219b2ee8SDavid du Colombier for(t = tuple->entry; t; t = t->entry){
907dd7cddfSDavid du Colombier if((offset = strtol(t->attr, 0, 0)) == 0)
91219b2ee8SDavid du Colombier continue;
92219b2ee8SDavid du Colombier
93219b2ee8SDavid du Colombier string = t->val;
94219b2ee8SDavid du Colombier len = strlen(string);
957dd7cddfSDavid du Colombier
967dd7cddfSDavid du Colombier if(p = strchr(t->attr, '-')) {
977dd7cddfSDavid du Colombier if((offset1 = strtol(p+1, 0, 0)) < offset+len)
987dd7cddfSDavid du Colombier continue;
997dd7cddfSDavid du Colombier } else
1007dd7cddfSDavid du Colombier offset1 = offset+len;
1017dd7cddfSDavid du Colombier
1027dd7cddfSDavid du Colombier if(vga->offset) {
1037dd7cddfSDavid du Colombier if(offset > vga->offset || vga->offset+len > offset1)
1047dd7cddfSDavid du Colombier continue;
1057dd7cddfSDavid du Colombier offset = vga->offset;
1067dd7cddfSDavid du Colombier offset1 = offset+len;
1077dd7cddfSDavid du Colombier }
1087dd7cddfSDavid du Colombier
1097dd7cddfSDavid du Colombier for(; offset+len<=offset1; offset++) {
1107dd7cddfSDavid du Colombier if(vga->bios)
1117dd7cddfSDavid du Colombier bios = vga->bios;
1127dd7cddfSDavid du Colombier else
1137dd7cddfSDavid du Colombier bios = readbios(len, offset);
114219b2ee8SDavid du Colombier if(strncmp(bios, string, len) == 0){
1159a747e4fSDavid du Colombier if(vga->bios == 0){
1169a747e4fSDavid du Colombier vga->bios = alloc(len+1);
1179a747e4fSDavid du Colombier strncpy(vga->bios, bios, len);
1189a747e4fSDavid du Colombier }
1197dd7cddfSDavid du Colombier addattr(&vga->attr, t);
1209a747e4fSDavid du Colombier return 1;
1219a747e4fSDavid du Colombier }
1229a747e4fSDavid du Colombier }
1239a747e4fSDavid du Colombier }
1249a747e4fSDavid du Colombier return 0;
1259a747e4fSDavid du Colombier }
1269a747e4fSDavid du Colombier
1279a747e4fSDavid du Colombier int
dbpci(Vga * vga,Ndbtuple * tuple)1289a747e4fSDavid du Colombier dbpci(Vga *vga, Ndbtuple *tuple)
1299a747e4fSDavid du Colombier {
1309a747e4fSDavid du Colombier int did, vid;
1319a747e4fSDavid du Colombier Ndbtuple *t, *td;
1329a747e4fSDavid du Colombier Pcidev *pci;
1339a747e4fSDavid du Colombier
1349a747e4fSDavid du Colombier for(t = tuple->entry; t; t = t->entry){
1359a747e4fSDavid du Colombier if(strcmp(t->attr, "vid") != 0 || (vid=atoi(t->val)) == 0)
1369a747e4fSDavid du Colombier continue;
1379a747e4fSDavid du Colombier for(td = t->line; td != t; td = td->line){
138fb7f0c93SDavid du Colombier if(strcmp(td->attr, "did") != 0)
139fb7f0c93SDavid du Colombier continue;
140fb7f0c93SDavid du Colombier if(strcmp(td->val, "*") == 0)
141fb7f0c93SDavid du Colombier did = 0;
142fb7f0c93SDavid du Colombier else if((did=atoi(td->val)) == 0)
143fb7f0c93SDavid du Colombier continue;
144fb7f0c93SDavid du Colombier for(pci=nil; pci=pcimatch(pci, vid, did);)
145fb7f0c93SDavid du Colombier if((pci->ccru>>8) == 3)
146fb7f0c93SDavid du Colombier break;
147fb7f0c93SDavid du Colombier if(pci == nil)
148fb7f0c93SDavid du Colombier continue;
1499a747e4fSDavid du Colombier vga->pci = pci;
1509a747e4fSDavid du Colombier addattr(&vga->attr, t);
1519a747e4fSDavid du Colombier addattr(&vga->attr, td);
1529a747e4fSDavid du Colombier return 1;
1539a747e4fSDavid du Colombier }
1549a747e4fSDavid du Colombier }
1559a747e4fSDavid du Colombier return 0;
1569a747e4fSDavid du Colombier }
1579a747e4fSDavid du Colombier
1589a747e4fSDavid du Colombier static void
save(Vga * vga,Ndbtuple * tuple)1599a747e4fSDavid du Colombier save(Vga *vga, Ndbtuple *tuple)
1609a747e4fSDavid du Colombier {
161*b0dcc5a8SDavid du Colombier Ctlr *c;
1629a747e4fSDavid du Colombier Ndbtuple *t;
1639a747e4fSDavid du Colombier
164219b2ee8SDavid du Colombier for(t = tuple->entry; t; t = t->entry){
165*b0dcc5a8SDavid du Colombier if(strcmp(t->attr, "ctlr") == 0){
166219b2ee8SDavid du Colombier vga->ctlr = addctlr(vga, t->val);
167*b0dcc5a8SDavid du Colombier if(strcmp(t->val, "vesa") == 0)
168*b0dcc5a8SDavid du Colombier vga->vesa = vga->ctlr;
169*b0dcc5a8SDavid du Colombier }else if(strcmp(t->attr, "ramdac") == 0)
170219b2ee8SDavid du Colombier vga->ramdac = addctlr(vga, t->val);
171219b2ee8SDavid du Colombier else if(strcmp(t->attr, "clock") == 0)
172219b2ee8SDavid du Colombier vga->clock = addctlr(vga, t->val);
173219b2ee8SDavid du Colombier else if(strcmp(t->attr, "hwgc") == 0)
174219b2ee8SDavid du Colombier vga->hwgc = addctlr(vga, t->val);
175*b0dcc5a8SDavid du Colombier else if(strcmp(t->attr, "link") == 0){
176*b0dcc5a8SDavid du Colombier c = addctlr(vga, t->val);
177*b0dcc5a8SDavid du Colombier if(strcmp(t->val, "vesa") == 0)
178*b0dcc5a8SDavid du Colombier vga->vesa = c;
179*b0dcc5a8SDavid du Colombier }else if(strcmp(t->attr, "linear") == 0)
1807dd7cddfSDavid du Colombier vga->linear = strtol(t->val, 0, 0);
1817dd7cddfSDavid du Colombier else if(strcmp(t->attr, "membw") == 0)
1827dd7cddfSDavid du Colombier vga->membw = strtol(t->val, 0, 0)*1000000;
1839a747e4fSDavid du Colombier else if(strcmp(t->attr, "vid")==0 || strcmp(t->attr, "did")==0)
1849a747e4fSDavid du Colombier {}
1857dd7cddfSDavid du Colombier else if(strtol(t->attr, 0, 0) == 0)
1867dd7cddfSDavid du Colombier addattr(&vga->attr, t);
187219b2ee8SDavid du Colombier }
1887dd7cddfSDavid du Colombier }
1897dd7cddfSDavid du Colombier
1909a747e4fSDavid du Colombier int
dbctlr(char * name,Vga * vga)1919a747e4fSDavid du Colombier dbctlr(char* name, Vga* vga)
1929a747e4fSDavid du Colombier {
1939a747e4fSDavid du Colombier Ndb *db;
1949a747e4fSDavid du Colombier Ndbs s;
1959a747e4fSDavid du Colombier Ndbtuple *tuple;
1969a747e4fSDavid du Colombier Ndbtuple *pcituple;
1979a747e4fSDavid du Colombier
1989a747e4fSDavid du Colombier db = dbopen(name);
1999a747e4fSDavid du Colombier
2009a747e4fSDavid du Colombier /*
2019a747e4fSDavid du Colombier * Search vgadb for a matching BIOS string or PCI id.
2029a747e4fSDavid du Colombier * If we have both, the BIOS string wins.
2039a747e4fSDavid du Colombier */
2049a747e4fSDavid du Colombier pcituple = nil;
2059a747e4fSDavid du Colombier for(tuple = ndbsearch(db, &s, "ctlr", ""); tuple; tuple = ndbsnext(&s, "ctlr", "")){
2069a747e4fSDavid du Colombier if(!pcituple && dbpci(vga, tuple))
2079a747e4fSDavid du Colombier pcituple = tuple;
2089a747e4fSDavid du Colombier if(dbbios(vga, tuple)){
2099a747e4fSDavid du Colombier save(vga, tuple);
2109a747e4fSDavid du Colombier if(pcituple && pcituple != tuple)
2119a747e4fSDavid du Colombier ndbfree(pcituple);
212219b2ee8SDavid du Colombier ndbfree(tuple);
213219b2ee8SDavid du Colombier ndbclose(db);
214219b2ee8SDavid du Colombier return 1;
215219b2ee8SDavid du Colombier }
2169a747e4fSDavid du Colombier if(tuple != pcituple)
217219b2ee8SDavid du Colombier ndbfree(tuple);
218219b2ee8SDavid du Colombier }
219219b2ee8SDavid du Colombier
2209a747e4fSDavid du Colombier if(pcituple){
2219a747e4fSDavid du Colombier save(vga, pcituple);
2229a747e4fSDavid du Colombier ndbfree(pcituple);
2239a747e4fSDavid du Colombier }
224219b2ee8SDavid du Colombier ndbclose(db);
2259a747e4fSDavid du Colombier if(pcituple)
2269a747e4fSDavid du Colombier return 1;
227219b2ee8SDavid du Colombier return 0;
228219b2ee8SDavid du Colombier }
229219b2ee8SDavid du Colombier
230219b2ee8SDavid du Colombier static int
dbmonitor(Ndb * db,Mode * mode,char * type,char * size)231219b2ee8SDavid du Colombier dbmonitor(Ndb* db, Mode* mode, char* type, char* size)
232219b2ee8SDavid du Colombier {
233219b2ee8SDavid du Colombier Ndbs s;
234219b2ee8SDavid du Colombier Ndbtuple *t, *tuple;
23557837e0bSDavid du Colombier char *p, attr[Namelen+1], val[Namelen+1], buf[2*Namelen+1];
236e0d6d19cSDavid du Colombier int clock, x, i;
2377dd7cddfSDavid du Colombier
2387dd7cddfSDavid du Colombier /*
2397dd7cddfSDavid du Colombier * Clock rate hack.
2407dd7cddfSDavid du Colombier * If the size is 'XxYxZ@NMHz' then override the database entry's
2417dd7cddfSDavid du Colombier * 'clock=' with 'N*1000000'.
2427dd7cddfSDavid du Colombier */
2437dd7cddfSDavid du Colombier clock = 0;
2447dd7cddfSDavid du Colombier strcpy(buf, size);
2457dd7cddfSDavid du Colombier if(p = strchr(buf, '@')){
2467dd7cddfSDavid du Colombier *p++ = 0;
2477dd7cddfSDavid du Colombier if((clock = strtol(p, &p, 0)) && strcmp(p, "MHz") == 0)
2487dd7cddfSDavid du Colombier clock *= 1000000;
2497dd7cddfSDavid du Colombier }
250219b2ee8SDavid du Colombier
251219b2ee8SDavid du Colombier memset(mode, 0, sizeof(Mode));
2527dd7cddfSDavid du Colombier
2537dd7cddfSDavid du Colombier if((p = strchr(buf, 'x')) && (p = strchr(p+1, 'x'))){
2547dd7cddfSDavid du Colombier *p++ = 0;
2557dd7cddfSDavid du Colombier mode->z = atoi(p);
2567dd7cddfSDavid du Colombier }
2577dd7cddfSDavid du Colombier
258219b2ee8SDavid du Colombier strcpy(attr, type);
2597dd7cddfSDavid du Colombier strcpy(val, buf);
2607dd7cddfSDavid du Colombier
26157837e0bSDavid du Colombier if(p = ndbgetvalue(db, &s, attr, "", "videobw", nil)){
26257837e0bSDavid du Colombier mode->videobw = atol(p)*1000000UL;
26357837e0bSDavid du Colombier free(p);
2647dd7cddfSDavid du Colombier }
265219b2ee8SDavid du Colombier
266219b2ee8SDavid du Colombier if(mode->x == 0 && ((mode->x = strtol(val, &p, 0)) == 0 || *p++ != 'x'))
267219b2ee8SDavid du Colombier return 0;
2687dd7cddfSDavid du Colombier if(mode->y == 0 && (mode->y = strtol(p, &p, 0)) == 0)
269219b2ee8SDavid du Colombier return 0;
270e0d6d19cSDavid du Colombier i = 0;
2717dd7cddfSDavid du Colombier buggery:
2727dd7cddfSDavid du Colombier if((tuple = ndbsearch(db, &s, attr, val)) == 0)
273219b2ee8SDavid du Colombier return 0;
274219b2ee8SDavid du Colombier
275219b2ee8SDavid du Colombier for(t = tuple->entry; t; t = t->entry){
276219b2ee8SDavid du Colombier if(strcmp(t->attr, "clock") == 0 && mode->frequency == 0)
277219b2ee8SDavid du Colombier mode->frequency = strtod(t->val, 0)*1000000;
2787dd7cddfSDavid du Colombier else if(strcmp(t->attr, "defaultclock") == 0 && mode->deffrequency == 0)
2797dd7cddfSDavid du Colombier mode->deffrequency = strtod(t->val, 0)*1000000;
280219b2ee8SDavid du Colombier else if(strcmp(t->attr, "ht") == 0 && mode->ht == 0)
281219b2ee8SDavid du Colombier mode->ht = strtol(t->val, 0, 0);
282219b2ee8SDavid du Colombier else if(strcmp(t->attr, "shb") == 0 && mode->shb == 0)
283219b2ee8SDavid du Colombier mode->shb = strtol(t->val, 0, 0);
284219b2ee8SDavid du Colombier else if(strcmp(t->attr, "ehb") == 0 && mode->ehb == 0)
285219b2ee8SDavid du Colombier mode->ehb = strtol(t->val, 0, 0);
2867dd7cddfSDavid du Colombier else if(strcmp(t->attr, "shs") == 0 && mode->shs == 0)
2877dd7cddfSDavid du Colombier mode->shs = strtol(t->val, 0, 0);
2887dd7cddfSDavid du Colombier else if(strcmp(t->attr, "ehs") == 0 && mode->ehs == 0)
2897dd7cddfSDavid du Colombier mode->ehs = strtol(t->val, 0, 0);
290219b2ee8SDavid du Colombier else if(strcmp(t->attr, "vt") == 0 && mode->vt == 0)
291219b2ee8SDavid du Colombier mode->vt = strtol(t->val, 0, 0);
292219b2ee8SDavid du Colombier else if(strcmp(t->attr, "vrs") == 0 && mode->vrs == 0)
293219b2ee8SDavid du Colombier mode->vrs = strtol(t->val, 0, 0);
294219b2ee8SDavid du Colombier else if(strcmp(t->attr, "vre") == 0 && mode->vre == 0)
295219b2ee8SDavid du Colombier mode->vre = strtol(t->val, 0, 0);
296219b2ee8SDavid du Colombier else if(strcmp(t->attr, "hsync") == 0)
297219b2ee8SDavid du Colombier mode->hsync = *t->val;
298219b2ee8SDavid du Colombier else if(strcmp(t->attr, "vsync") == 0)
299219b2ee8SDavid du Colombier mode->vsync = *t->val;
300219b2ee8SDavid du Colombier else if(strcmp(t->attr, "interlace") == 0)
301219b2ee8SDavid du Colombier mode->interlace = *t->val;
3027dd7cddfSDavid du Colombier else if(strcmp(t->attr, "include") == 0 /*&& strcmp(t->val, val) != 0*/){
303219b2ee8SDavid du Colombier strcpy(attr, t->attr);
304219b2ee8SDavid du Colombier strcpy(val, t->val);
305219b2ee8SDavid du Colombier ndbfree(tuple);
306e0d6d19cSDavid du Colombier if(i++ > 5)
307e0d6d19cSDavid du Colombier error("dbmonitor: implausible include depth at %s=%s\n", attr, val);
308219b2ee8SDavid du Colombier goto buggery;
309219b2ee8SDavid du Colombier }
3107dd7cddfSDavid du Colombier else if(strcmp(t->attr, "include") == 0){
3117dd7cddfSDavid du Colombier print("warning: bailed out of infinite loop in attr %s=%s\n", attr, val);
3127dd7cddfSDavid du Colombier }
3137dd7cddfSDavid du Colombier else
3147dd7cddfSDavid du Colombier addattr(&mode->attr, t);
315219b2ee8SDavid du Colombier }
316219b2ee8SDavid du Colombier ndbfree(tuple);
317219b2ee8SDavid du Colombier
318219b2ee8SDavid du Colombier if((x = strtol(size, &p, 0)) == 0 || x != mode->x || *p++ != 'x')
319219b2ee8SDavid du Colombier return 0;
320219b2ee8SDavid du Colombier if((x = strtol(p, &p, 0)) == 0 || x != mode->y || *p++ != 'x')
321219b2ee8SDavid du Colombier return 0;
322219b2ee8SDavid du Colombier if((x = strtol(p, &p, 0)) == 0 || x != mode->z)
323219b2ee8SDavid du Colombier return 0;
324219b2ee8SDavid du Colombier
3257dd7cddfSDavid du Colombier if(clock)
3267dd7cddfSDavid du Colombier mode->frequency = clock;
3277dd7cddfSDavid du Colombier
328219b2ee8SDavid du Colombier return 1;
329219b2ee8SDavid du Colombier }
330219b2ee8SDavid du Colombier
331219b2ee8SDavid du Colombier Mode*
dbmode(char * name,char * type,char * size)332219b2ee8SDavid du Colombier dbmode(char* name, char* type, char* size)
333219b2ee8SDavid du Colombier {
334219b2ee8SDavid du Colombier Ndb *db;
335219b2ee8SDavid du Colombier Ndbs s;
336219b2ee8SDavid du Colombier Ndbtuple *t, *tuple;
337219b2ee8SDavid du Colombier Mode *mode;
3389a747e4fSDavid du Colombier char attr[Namelen+1];
3397dd7cddfSDavid du Colombier ulong videobw;
340219b2ee8SDavid du Colombier
341219b2ee8SDavid du Colombier db = dbopen(name);
342219b2ee8SDavid du Colombier mode = alloc(sizeof(Mode));
343219b2ee8SDavid du Colombier strcpy(attr, type);
344219b2ee8SDavid du Colombier
3457dd7cddfSDavid du Colombier videobw = 0;
346219b2ee8SDavid du Colombier /*
347219b2ee8SDavid du Colombier * Look for the attr=size entry.
348219b2ee8SDavid du Colombier */
349219b2ee8SDavid du Colombier if(dbmonitor(db, mode, attr, size)){
350219b2ee8SDavid du Colombier strcpy(mode->type, type);
351219b2ee8SDavid du Colombier strcpy(mode->size, size);
352219b2ee8SDavid du Colombier ndbclose(db);
353219b2ee8SDavid du Colombier return mode;
354219b2ee8SDavid du Colombier }
355219b2ee8SDavid du Colombier
3567dd7cddfSDavid du Colombier if(mode->videobw && videobw == 0) /* we at least found that; save it away */
3577dd7cddfSDavid du Colombier videobw = mode->videobw;
3587dd7cddfSDavid du Colombier
359219b2ee8SDavid du Colombier /*
360219b2ee8SDavid du Colombier * Not found. Look for an attr="" entry and then
361219b2ee8SDavid du Colombier * for an alias=attr within.
362219b2ee8SDavid du Colombier */
363219b2ee8SDavid du Colombier buggery:
364219b2ee8SDavid du Colombier for(tuple = ndbsearch(db, &s, attr, ""); tuple; tuple = ndbsnext(&s, attr, "")){
365219b2ee8SDavid du Colombier for(t = tuple->entry; t; t = t->entry){
366219b2ee8SDavid du Colombier if(strcmp(t->attr, "alias"))
367219b2ee8SDavid du Colombier continue;
368219b2ee8SDavid du Colombier strcpy(attr, t->val);
369219b2ee8SDavid du Colombier if(dbmonitor(db, mode, attr, size)){
370219b2ee8SDavid du Colombier strcpy(mode->type, type);
371219b2ee8SDavid du Colombier strcpy(mode->size, size);
372219b2ee8SDavid du Colombier ndbfree(tuple);
373219b2ee8SDavid du Colombier ndbclose(db);
3747dd7cddfSDavid du Colombier if(videobw)
3757dd7cddfSDavid du Colombier mode->videobw = videobw;
376219b2ee8SDavid du Colombier return mode;
377219b2ee8SDavid du Colombier }
378219b2ee8SDavid du Colombier
379219b2ee8SDavid du Colombier /*
380219b2ee8SDavid du Colombier * Found an alias but no match for size,
381219b2ee8SDavid du Colombier * restart looking for attr="" with the
382219b2ee8SDavid du Colombier * new attr.
383219b2ee8SDavid du Colombier */
384219b2ee8SDavid du Colombier ndbfree(tuple);
385219b2ee8SDavid du Colombier goto buggery;
386219b2ee8SDavid du Colombier }
387219b2ee8SDavid du Colombier ndbfree(tuple);
388219b2ee8SDavid du Colombier }
389219b2ee8SDavid du Colombier
390219b2ee8SDavid du Colombier free(mode);
391219b2ee8SDavid du Colombier ndbclose(db);
392219b2ee8SDavid du Colombier return 0;
393219b2ee8SDavid du Colombier }
394219b2ee8SDavid du Colombier
395219b2ee8SDavid du Colombier void
dbdumpmode(Mode * mode)396219b2ee8SDavid du Colombier dbdumpmode(Mode* mode)
397219b2ee8SDavid du Colombier {
3987dd7cddfSDavid du Colombier Attr *attr;
399219b2ee8SDavid du Colombier
4007dd7cddfSDavid du Colombier Bprint(&stdout, "dbdumpmode\n");
4017dd7cddfSDavid du Colombier
4027dd7cddfSDavid du Colombier Bprint(&stdout, "type=%s, size=%s\n", mode->type, mode->size);
4037dd7cddfSDavid du Colombier Bprint(&stdout, "frequency=%d\n", mode->frequency);
4047dd7cddfSDavid du Colombier Bprint(&stdout, "x=%d (0x%X), y=%d (0x%X), z=%d (0x%X)\n",
405219b2ee8SDavid du Colombier mode->x, mode->x, mode->y, mode->y, mode->z, mode->z);
4067dd7cddfSDavid du Colombier Bprint(&stdout, "ht=%d (0x%X), shb=%d (0x%X), ehb=%d (0x%X)\n",
407219b2ee8SDavid du Colombier mode->ht, mode->ht, mode->shb, mode->shb, mode->ehb, mode->ehb);
4087dd7cddfSDavid du Colombier Bprint(&stdout, "shs=%d (0x%X), ehs=%d (0x%X)\n",
4097dd7cddfSDavid du Colombier mode->shs, mode->shs, mode->ehs, mode->ehs);
4107dd7cddfSDavid du Colombier Bprint(&stdout, "vt=%d (0x%X), vrs=%d (0x%X), vre=%d (0x%X)\n",
411219b2ee8SDavid du Colombier mode->vt, mode->vt, mode->vrs, mode->vrs, mode->vre, mode->vre);
4127dd7cddfSDavid du Colombier Bprint(&stdout, "hsync=%d, vsync=%d, interlace=%d\n",
413219b2ee8SDavid du Colombier mode->hsync, mode->vsync, mode->interlace);
4147dd7cddfSDavid du Colombier
4157dd7cddfSDavid du Colombier for(attr = mode->attr; attr; attr = attr->next)
4167dd7cddfSDavid du Colombier Bprint(&stdout, "mode->attr: %s=%s\n", attr->attr, attr->val);
417219b2ee8SDavid du Colombier }
418