Imported Upstream version 1.15.1
[deb_xorg-server.git] / hw / xfree86 / common / xf86sbusBus.c
CommitLineData
a09e091a
JB
1/*
2 * SBUS bus-specific code.
3 *
4 * Copyright (C) 2000 Jakub Jelinek (jakub@redhat.com)
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * JAKUB JELINEK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
23
24#ifdef HAVE_XORG_CONFIG_H
25#include <xorg-config.h>
26#endif
27
28#include <ctype.h>
29#include <stdio.h>
30#include <unistd.h>
31#include <X11/X.h>
32#include "os.h"
33#include "xf86.h"
34#include "xf86Priv.h"
35#include "xf86_OSlib.h"
36#include "xf86cmap.h"
37
38#include "xf86Bus.h"
39
40#include "xf86sbusBus.h"
41#include "xf86Sbus.h"
42
43Bool sbusSlotClaimed = FALSE;
44
45static int xf86nSbusInfo;
46
47static void
48CheckSbusDevice(const char *device, int fbNum)
49{
50 int fd, i;
51 struct fbgattr fbattr;
52 sbusDevicePtr psdp;
53
54 fd = open(device, O_RDONLY, 0);
55 if (fd < 0)
56 return;
57 memset(&fbattr, 0, sizeof(fbattr));
58 if (ioctl(fd, FBIOGATTR, &fbattr) < 0) {
59 if (ioctl(fd, FBIOGTYPE, &fbattr.fbtype) < 0) {
60 close(fd);
61 return;
62 }
63 }
64 close(fd);
65 for (i = 0; sbusDeviceTable[i].devId; i++)
66 if (sbusDeviceTable[i].fbType == fbattr.fbtype.fb_type)
67 break;
68 if (!sbusDeviceTable[i].devId)
69 return;
70 xf86SbusInfo =
71 xnfrealloc(xf86SbusInfo, sizeof(psdp) * (++xf86nSbusInfo + 1));
72 xf86SbusInfo[xf86nSbusInfo] = NULL;
73 xf86SbusInfo[xf86nSbusInfo - 1] = psdp = xnfcalloc(sizeof(sbusDevice), 1);
74 psdp->devId = sbusDeviceTable[i].devId;
75 psdp->fbNum = fbNum;
76 psdp->device = xnfstrdup(device);
77 psdp->width = fbattr.fbtype.fb_width;
78 psdp->height = fbattr.fbtype.fb_height;
79 psdp->fd = -1;
80}
81
82void
83xf86SbusProbe(void)
84{
85 int i, useProm = 0;
86 char fbDevName[32];
87 sbusDevicePtr psdp, *psdpp;
88
89 xf86SbusInfo = malloc(sizeof(psdp));
90 *xf86SbusInfo = NULL;
91 for (i = 0; i < 32; i++) {
92 snprintf(fbDevName, sizeof(fbDevName), "/dev/fb%d", i);
93 CheckSbusDevice(fbDevName, i);
94 }
95 if (sparcPromInit() >= 0) {
96 useProm = 1;
97 sparcPromAssignNodes();
98 }
99 for (psdpp = xf86SbusInfo; (psdp = *psdpp); psdpp++) {
100 for (i = 0; sbusDeviceTable[i].devId; i++)
101 if (sbusDeviceTable[i].devId == psdp->devId)
102 psdp->descr = sbusDeviceTable[i].descr;
103 /*
104 * If we can use PROM information and found the PROM node for this
105 * device, we can tell more about the card.
106 */
107 if (useProm && psdp->node.node) {
108 char *prop, *promPath;
109 int len, chiprev, vmsize;
110
111 switch (psdp->devId) {
112 case SBUS_DEVICE_MGX:
113 prop = sparcPromGetProperty(&psdp->node, "fb_size", &len);
114 if (prop && len == 4 && *(int *) prop == 0x400000)
115 psdp->descr = "Quantum 3D MGXplus with 4M VRAM";
116 break;
117 case SBUS_DEVICE_CG6:
118 chiprev = 0;
119 vmsize = 0;
120 prop = sparcPromGetProperty(&psdp->node, "chiprev", &len);
121 if (prop && len == 4)
122 chiprev = *(int *) prop;
123 prop = sparcPromGetProperty(&psdp->node, "vmsize", &len);
124 if (prop && len == 4)
125 vmsize = *(int *) prop;
126 switch (chiprev) {
127 case 1:
128 case 2:
129 case 3:
130 case 4:
131 psdp->descr = "Sun Double width GX";
132 break;
133 case 5:
134 case 6:
135 case 7:
136 case 8:
137 case 9:
138 psdp->descr = "Sun Single width GX";
139 break;
140 case 11:
141 switch (vmsize) {
142 case 2:
143 psdp->descr = "Sun Turbo GX with 1M VSIMM";
144 break;
145 case 4:
146 psdp->descr = "Sun Turbo GX Plus";
147 break;
148 default:
149 psdp->descr = "Sun Turbo GX";
150 break;
151 }
152 }
153 break;
154 case SBUS_DEVICE_CG14:
155 prop = sparcPromGetProperty(&psdp->node, "reg", &len);
156 vmsize = 0;
157 if (prop && !(len % 12) && len > 0)
158 vmsize = *(int *) (prop + len - 4);
159 switch (vmsize) {
160 case 0x400000:
161 psdp->descr = "Sun SX with 4M VSIMM";
162 break;
163 case 0x800000:
164 psdp->descr = "Sun SX with 8M VSIMM";
165 break;
166 }
167 break;
168 case SBUS_DEVICE_LEO:
169 prop = sparcPromGetProperty(&psdp->node, "model", &len);
170 if (prop && len > 0 && !strstr(prop, "501-2503"))
171 psdp->descr = "Sun Turbo ZX";
172 break;
173 case SBUS_DEVICE_TCX:
174 if (sparcPromGetBool(&psdp->node, "tcx-8-bit"))
175 psdp->descr = "Sun TCX (8bit)";
176 else
177 psdp->descr = "Sun TCX (S24)";
178 break;
179 case SBUS_DEVICE_FFB:
180 prop = sparcPromGetProperty(&psdp->node, "name", &len);
181 chiprev = 0;
182 prop = sparcPromGetProperty(&psdp->node, "board_type", &len);
183 if (prop && len == 4)
184 chiprev = *(int *) prop;
185 if (strstr(prop, "afb")) {
186 if (chiprev == 3)
187 psdp->descr = "Sun|Elite3D-M6 Horizontal";
188 }
189 else {
190 switch (chiprev) {
191 case 0x08:
192 psdp->descr = "Sun FFB 67MHz Creator";
193 break;
194 case 0x0b:
195 psdp->descr = "Sun FFB 67MHz Creator 3D";
196 break;
197 case 0x1b:
198 psdp->descr = "Sun FFB 75MHz Creator 3D";
199 break;
200 case 0x20:
201 case 0x28:
202 psdp->descr = "Sun FFB2 Vertical Creator";
203 break;
204 case 0x23:
205 case 0x2b:
206 psdp->descr = "Sun FFB2 Vertical Creator 3D";
207 break;
208 case 0x30:
209 psdp->descr = "Sun FFB2+ Vertical Creator";
210 break;
211 case 0x33:
212 psdp->descr = "Sun FFB2+ Vertical Creator 3D";
213 break;
214 case 0x40:
215 case 0x48:
216 psdp->descr = "Sun FFB2 Horizontal Creator";
217 break;
218 case 0x43:
219 case 0x4b:
220 psdp->descr = "Sun FFB2 Horizontal Creator 3D";
221 break;
222 }
223 }
224 break;
225 }
226
227 xf86Msg(X_PROBED, "SBUS:(0x%08x) %s", psdp->node.node, psdp->descr);
228 promPath = sparcPromNode2Pathname(&psdp->node);
229 if (promPath) {
230 xf86ErrorF(" at %s", promPath);
231 free(promPath);
232 }
233 }
234 else
235 xf86Msg(X_PROBED, "SBUS: %s", psdp->descr);
236 xf86ErrorF("\n");
237 }
238 if (useProm)
239 sparcPromClose();
240}
241
242/*
243 * Parse a BUS ID string, and return the SBUS bus parameters if it was
244 * in the correct format for a SBUS bus id.
245 */
246
247Bool
248xf86ParseSbusBusString(const char *busID, int *fbNum)
249{
250 /*
251 * The format is assumed to be one of:
252 * "fbN", e.g. "fb1", which means the device corresponding to /dev/fbN
253 * "nameN", e.g. "cgsix0", which means Nth instance of card NAME
254 * "/prompath", e.g. "/sbus@0,10001000/cgsix@3,0" which is PROM pathname
255 * to the device.
256 */
257
258 const char *id;
259 int i, len;
260
261 if (StringToBusType(busID, &id) != BUS_SBUS)
262 return FALSE;
263
264 if (*id != '/') {
265 if (!strncmp(id, "fb", 2)) {
266 if (!isdigit(id[2]))
267 return FALSE;
268 *fbNum = atoi(id + 2);
269 return TRUE;
270 }
271 else {
272 sbusDevicePtr *psdpp;
273 int devId;
274
275 for (i = 0, len = 0; sbusDeviceTable[i].devId; i++) {
276 len = strlen(sbusDeviceTable[i].promName);
277 if (!strncmp(sbusDeviceTable[i].promName, id, len)
278 && isdigit(id[len]))
279 break;
280 }
281 devId = sbusDeviceTable[i].devId;
282 if (!devId)
283 return FALSE;
284 i = atoi(id + len);
285 for (psdpp = xf86SbusInfo; *psdpp; ++psdpp) {
286 if ((*psdpp)->devId != devId)
287 continue;
288 if (!i) {
289 *fbNum = (*psdpp)->fbNum;
290 return TRUE;
291 }
292 i--;
293 }
294 }
295 return FALSE;
296 }
297
298 if (sparcPromInit() >= 0) {
299 i = sparcPromPathname2Node(id);
300 sparcPromClose();
301 if (i) {
302 sbusDevicePtr *psdpp;
303
304 for (psdpp = xf86SbusInfo; *psdpp; ++psdpp) {
305 if ((*psdpp)->node.node == i) {
306 *fbNum = (*psdpp)->fbNum;
307 return TRUE;
308 }
309 }
310 }
311 }
312 return FALSE;
313}
314
315/*
316 * Compare a BUS ID string with a SBUS bus id. Return TRUE if they match.
317 */
318
319Bool
320xf86CompareSbusBusString(const char *busID, int fbNum)
321{
322 int iFbNum;
323
324 if (xf86ParseSbusBusString(busID, &iFbNum)) {
325 return fbNum == iFbNum;
326 }
327 else {
328 return FALSE;
329 }
330}
331
332/*
333 * Check if the slot requested is free. If it is already in use, return FALSE.
334 */
335
336Bool
337xf86CheckSbusSlot(int fbNum)
338{
339 int i;
340 EntityPtr p;
341
342 for (i = 0; i < xf86NumEntities; i++) {
343 p = xf86Entities[i];
344 /* Check if this SBUS slot is taken */
345 if (p->bus.type == BUS_SBUS && p->bus.id.sbus.fbNum == fbNum)
346 return FALSE;
347 }
348
349 return TRUE;
350}
351
352/*
353 * If the slot requested is already in use, return -1.
354 * Otherwise, claim the slot for the screen requesting it.
355 */
356
357int
358xf86ClaimSbusSlot(sbusDevicePtr psdp, DriverPtr drvp, GDevPtr dev, Bool active)
359{
360 EntityPtr p = NULL;
361
362 int num;
363
364 if (xf86CheckSbusSlot(psdp->fbNum)) {
365 num = xf86AllocateEntity();
366 p = xf86Entities[num];
367 p->driver = drvp;
368 p->chipset = -1;
369 p->bus.type = BUS_SBUS;
370 xf86AddDevToEntity(num, dev);
371 p->bus.id.sbus.fbNum = psdp->fbNum;
372 p->active = active;
373 p->inUse = FALSE;
374 sbusSlotClaimed = TRUE;
375 return num;
376 }
377 else
378 return -1;
379}
380
381int
382xf86MatchSbusInstances(const char *driverName, int sbusDevId,
383 GDevPtr * devList, int numDevs, DriverPtr drvp,
384 int **foundEntities)
385{
386 int i, j;
387 sbusDevicePtr psdp, *psdpp;
388 int numClaimedInstances = 0;
389 int allocatedInstances = 0;
390 int numFound = 0;
391 GDevPtr devBus = NULL;
392 GDevPtr dev = NULL;
393 int *retEntities = NULL;
394 int useProm = 0;
395
396 struct Inst {
397 sbusDevicePtr sbus;
398 GDevPtr dev;
399 Bool claimed; /* BusID matches with a device section */
400 } *instances = NULL;
401
402 *foundEntities = NULL;
403 for (psdpp = xf86SbusInfo, psdp = *psdpp; psdp; psdp = *++psdpp) {
404 if (psdp->devId != sbusDevId)
405 continue;
406 if (psdp->fd == -2)
407 continue;
408 ++allocatedInstances;
409 instances = xnfrealloc(instances,
410 allocatedInstances * sizeof(struct Inst));
411 instances[allocatedInstances - 1].sbus = psdp;
412 instances[allocatedInstances - 1].dev = NULL;
413 instances[allocatedInstances - 1].claimed = FALSE;
414 numFound++;
415 }
416
417 /*
418 * This may be debatable, but if no SBUS devices with a matching vendor
419 * type is found, return zero now. It is probably not desirable to
420 * allow the config file to override this.
421 */
422 if (allocatedInstances <= 0) {
423 free(instances);
424 return 0;
425 }
426
427 if (sparcPromInit() >= 0)
428 useProm = 1;
429
430 if (xf86DoConfigure && xf86DoConfigurePass1) {
431 GDevPtr pGDev;
432 int actualcards = 0;
433
434 for (i = 0; i < allocatedInstances; i++) {
435 actualcards++;
436 pGDev = xf86AddBusDeviceToConfigure(drvp->driverName, BUS_SBUS,
437 instances[i].sbus, -1);
438 if (pGDev) {
439 /*
440 * XF86Match???Instances() treat chipID and chipRev as
441 * overrides, so clobber them here.
442 */
443 pGDev->chipID = pGDev->chipRev = -1;
444 }
445 }
446 free(instances);
447 if (useProm)
448 sparcPromClose();
449 return actualcards;
450 }
451
452 DebugF("%s instances found: %d\n", driverName, allocatedInstances);
453
454 for (i = 0; i < allocatedInstances; i++) {
455 char *promPath = NULL;
456
457 psdp = instances[i].sbus;
458 devBus = NULL;
459 dev = NULL;
460 if (useProm && psdp->node.node)
461 promPath = sparcPromNode2Pathname(&psdp->node);
462
463 for (j = 0; j < numDevs; j++) {
464 if (devList[j]->busID && *devList[j]->busID) {
465 if (xf86CompareSbusBusString(devList[j]->busID, psdp->fbNum)) {
466 if (devBus)
467 xf86MsgVerb(X_WARNING, 0,
468 "%s: More than one matching Device section for "
469 "instance (BusID: %s) found: %s\n",
470 driverName, devList[j]->identifier,
471 devList[j]->busID);
472 else
473 devBus = devList[j];
474 }
475 }
476 else {
477 if (!dev && !devBus) {
478 if (promPath)
479 xf86Msg(X_PROBED,
480 "Assigning device section with no busID to SBUS:%s\n",
481 promPath);
482 else
483 xf86Msg(X_PROBED,
484 "Assigning device section with no busID to SBUS:fb%d\n",
485 psdp->fbNum);
486 dev = devList[j];
487 }
488 else
489 xf86MsgVerb(X_WARNING, 0,
490 "%s: More than one matching Device section "
491 "found: %s\n", driverName,
492 devList[j]->identifier);
493 }
494 }
495 if (devBus)
496 dev = devBus; /* busID preferred */
497 if (!dev && psdp->fd != -2) {
498 if (promPath) {
499 xf86MsgVerb(X_WARNING, 0, "%s: No matching Device section "
500 "for instance (BusID SBUS:%s) found\n",
501 driverName, promPath);
502 }
503 else
504 xf86MsgVerb(X_WARNING, 0, "%s: No matching Device section "
505 "for instance (BusID SBUS:fb%d) found\n",
506 driverName, psdp->fbNum);
507 }
508 else if (dev) {
509 numClaimedInstances++;
510 instances[i].claimed = TRUE;
511 instances[i].dev = dev;
512 }
513 free(promPath);
514 }
515
516 DebugF("%s instances found: %d\n", driverName, numClaimedInstances);
517
518 /*
519 * Of the claimed instances, check that another driver hasn't already
520 * claimed its slot.
521 */
522 numFound = 0;
523 for (i = 0; i < allocatedInstances && numClaimedInstances > 0; i++) {
524 if (!instances[i].claimed)
525 continue;
526 psdp = instances[i].sbus;
527 if (!xf86CheckSbusSlot(psdp->fbNum))
528 continue;
529
530 DebugF("%s: card at fb%d %08x is claimed by a Device section\n",
531 driverName, psdp->fbNum, psdp->node.node);
532
533 /* Allocate an entry in the lists to be returned */
534 numFound++;
535 retEntities = xnfrealloc(retEntities, numFound * sizeof(int));
536 retEntities[numFound - 1]
537 = xf86ClaimSbusSlot(psdp, drvp, instances[i].dev,
538 instances[i].dev->active ? TRUE : FALSE);
539 }
540 free(instances);
541 if (numFound > 0) {
542 *foundEntities = retEntities;
543 }
544
545 if (useProm)
546 sparcPromClose();
547
548 return numFound;
549}
550
551/*
552 * xf86GetSbusInfoForEntity() -- Get the sbusDevicePtr of entity.
553 */
554sbusDevicePtr
555xf86GetSbusInfoForEntity(int entityIndex)
556{
557 sbusDevicePtr *psdpp;
558 EntityPtr p = xf86Entities[entityIndex];
559
560 if (entityIndex >= xf86NumEntities || p->bus.type != BUS_SBUS)
561 return NULL;
562
563 for (psdpp = xf86SbusInfo; *psdpp != NULL; psdpp++) {
564 if (p->bus.id.sbus.fbNum == (*psdpp)->fbNum)
565 return *psdpp;
566 }
567 return NULL;
568}
569
570int
571xf86GetEntityForSbusInfo(sbusDevicePtr psdp)
572{
573 int i;
574
575 for (i = 0; i < xf86NumEntities; i++) {
576 EntityPtr p = xf86Entities[i];
577
578 if (p->bus.type != BUS_SBUS)
579 continue;
580
581 if (p->bus.id.sbus.fbNum == psdp->fbNum)
582 return i;
583 }
584 return -1;
585}
586
587void
588xf86SbusUseBuiltinMode(ScrnInfoPtr pScrn, sbusDevicePtr psdp)
589{
590 DisplayModePtr mode;
591
592 mode = xnfcalloc(sizeof(DisplayModeRec), 1);
593 mode->name = "current";
594 mode->next = mode;
595 mode->prev = mode;
596 mode->type = M_T_BUILTIN;
597 mode->Clock = 100000000;
598 mode->HDisplay = psdp->width;
599 mode->HSyncStart = psdp->width;
600 mode->HSyncEnd = psdp->width;
601 mode->HTotal = psdp->width;
602 mode->VDisplay = psdp->height;
603 mode->VSyncStart = psdp->height;
604 mode->VSyncEnd = psdp->height;
605 mode->VTotal = psdp->height;
606 mode->SynthClock = mode->Clock;
607 mode->CrtcHDisplay = mode->HDisplay;
608 mode->CrtcHSyncStart = mode->HSyncStart;
609 mode->CrtcHSyncEnd = mode->HSyncEnd;
610 mode->CrtcHTotal = mode->HTotal;
611 mode->CrtcVDisplay = mode->VDisplay;
612 mode->CrtcVSyncStart = mode->VSyncStart;
613 mode->CrtcVSyncEnd = mode->VSyncEnd;
614 mode->CrtcVTotal = mode->VTotal;
615 mode->CrtcHAdjusted = FALSE;
616 mode->CrtcVAdjusted = FALSE;
617 pScrn->modes = mode;
618 pScrn->virtualX = psdp->width;
619 pScrn->virtualY = psdp->height;
620}
621
622static DevPrivateKeyRec sbusPaletteKeyRec;
623#define sbusPaletteKey (&sbusPaletteKeyRec)
624
625typedef struct _sbusCmap {
626 sbusDevicePtr psdp;
627 CloseScreenProcPtr CloseScreen;
628 Bool origCmapValid;
629 unsigned char origRed[16];
630 unsigned char origGreen[16];
631 unsigned char origBlue[16];
632} sbusCmapRec, *sbusCmapPtr;
633
634#define SBUSCMAPPTR(pScreen) ((sbusCmapPtr) \
635 dixLookupPrivate(&(pScreen)->devPrivates, sbusPaletteKey))
636
637static void
638xf86SbusCmapLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
639 LOCO * colors, VisualPtr pVisual)
640{
641 int i, index;
642 sbusCmapPtr cmap;
643 struct fbcmap fbcmap;
644 unsigned char *data;
645
646 cmap = SBUSCMAPPTR(pScrn->pScreen);
647 if (!cmap)
648 return;
649 fbcmap.count = 0;
650 fbcmap.index = indices[0];
651 fbcmap.red = data = malloc(numColors * 3);
652 if (!data)
653 return;
654 fbcmap.green = data + numColors;
655 fbcmap.blue = fbcmap.green + numColors;
656 for (i = 0; i < numColors; i++) {
657 index = indices[i];
658 if (fbcmap.count && index != fbcmap.index + fbcmap.count) {
659 ioctl(cmap->psdp->fd, FBIOPUTCMAP, &fbcmap);
660 fbcmap.count = 0;
661 fbcmap.index = index;
662 }
663 fbcmap.red[fbcmap.count] = colors[index].red;
664 fbcmap.green[fbcmap.count] = colors[index].green;
665 fbcmap.blue[fbcmap.count++] = colors[index].blue;
666 }
667 ioctl(cmap->psdp->fd, FBIOPUTCMAP, &fbcmap);
668 free(data);
669}
670
671static Bool
672xf86SbusCmapCloseScreen(ScreenPtr pScreen)
673{
674 sbusCmapPtr cmap;
675 struct fbcmap fbcmap;
676
677 cmap = SBUSCMAPPTR(pScreen);
678 if (cmap->origCmapValid) {
679 fbcmap.index = 0;
680 fbcmap.count = 16;
681 fbcmap.red = cmap->origRed;
682 fbcmap.green = cmap->origGreen;
683 fbcmap.blue = cmap->origBlue;
684 ioctl(cmap->psdp->fd, FBIOPUTCMAP, &fbcmap);
685 }
686 pScreen->CloseScreen = cmap->CloseScreen;
687 free(cmap);
688 return (*pScreen->CloseScreen) (pScreen);
689}
690
691Bool
692xf86SbusHandleColormaps(ScreenPtr pScreen, sbusDevicePtr psdp)
693{
694 sbusCmapPtr cmap;
695 struct fbcmap fbcmap;
696 unsigned char data[2];
697
698 if (!dixRegisterPrivateKey(sbusPaletteKey, PRIVATE_SCREEN, 0))
699 FatalError("Cannot register sbus private key");
700
701 cmap = xnfcalloc(1, sizeof(sbusCmapRec));
702 dixSetPrivate(&pScreen->devPrivates, sbusPaletteKey, cmap);
703 cmap->psdp = psdp;
704 fbcmap.index = 0;
705 fbcmap.count = 16;
706 fbcmap.red = cmap->origRed;
707 fbcmap.green = cmap->origGreen;
708 fbcmap.blue = cmap->origBlue;
709 if (ioctl(psdp->fd, FBIOGETCMAP, &fbcmap) >= 0)
710 cmap->origCmapValid = TRUE;
711 fbcmap.index = 0;
712 fbcmap.count = 2;
713 fbcmap.red = data;
714 fbcmap.green = data;
715 fbcmap.blue = data;
716 if (pScreen->whitePixel == 0) {
717 data[0] = 255;
718 data[1] = 0;
719 }
720 else {
721 data[0] = 0;
722 data[1] = 255;
723 }
724 ioctl(psdp->fd, FBIOPUTCMAP, &fbcmap);
725 cmap->CloseScreen = pScreen->CloseScreen;
726 pScreen->CloseScreen = xf86SbusCmapCloseScreen;
727 return xf86HandleColormaps(pScreen, 256, 8,
728 xf86SbusCmapLoadPalette, NULL, 0);
729}
730
731Bool
732xf86SbusConfigure(void *busData, sbusDevicePtr sBus)
733{
734 if (sBus && sBus->fbNum == ((sbusDevicePtr) busData)->fbNum)
735 return 0;
736 return 1;
737}
738
739void
740xf86SbusConfigureNewDev(void *busData, sbusDevicePtr sBus, GDevRec * GDev)
741{
742 char *promPath = NULL;
743
744 sBus = (sbusDevicePtr) busData;
745 GDev->identifier = sBus->descr;
746 if (sparcPromInit() >= 0) {
747 promPath = sparcPromNode2Pathname(&sBus->node);
748 sparcPromClose();
749 }
750 if (promPath) {
751 XNFasprintf(&GDev->busID, "SBUS:%s", promPath);
752 free(promPath);
753 }
754 else {
755 XNFasprintf(&GDev->busID, "SBUS:fb%d", sBus->fbNum);
756 }
757}