xf86sbusBus.c revision 706f2543
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 = xnfrealloc(xf86SbusInfo, sizeof(psdp) * (++xf86nSbusInfo + 1)); 71 xf86SbusInfo[xf86nSbusInfo] = NULL; 72 xf86SbusInfo[xf86nSbusInfo - 1] = psdp = xnfcalloc(sizeof (sbusDevice), 1); 73 psdp->devId = sbusDeviceTable[i].devId; 74 psdp->fbNum = fbNum; 75 psdp->device = xnfstrdup(device); 76 psdp->width = fbattr.fbtype.fb_width; 77 psdp->height = fbattr.fbtype.fb_height; 78 psdp->size = fbattr.fbtype.fb_size; 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 sprintf(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"; break; 132 case 5: 133 case 6: 134 case 7: 135 case 8: 136 case 9: 137 psdp->descr = "Sun Single width GX"; break; 138 case 11: 139 switch (vmsize) { 140 case 2: 141 psdp->descr = "Sun Turbo GX with 1M VSIMM"; break; 142 case 4: 143 psdp->descr = "Sun Turbo GX Plus"; break; 144 default: 145 psdp->descr = "Sun Turbo GX"; break; 146 } 147 } 148 break; 149 case SBUS_DEVICE_CG14: 150 prop = sparcPromGetProperty(&psdp->node, "reg", &len); 151 vmsize = 0; 152 if (prop && !(len % 12) && len > 0) 153 vmsize = *(int *)(prop + len - 4); 154 switch (vmsize) { 155 case 0x400000: 156 psdp->descr = "Sun SX with 4M VSIMM"; break; 157 case 0x800000: 158 psdp->descr = "Sun SX with 8M VSIMM"; break; 159 } 160 break; 161 case SBUS_DEVICE_LEO: 162 prop = sparcPromGetProperty(&psdp->node, "model", &len); 163 if (prop && len > 0 && !strstr(prop, "501-2503")) 164 psdp->descr = "Sun Turbo ZX"; 165 break; 166 case SBUS_DEVICE_TCX: 167 if (sparcPromGetBool(&psdp->node, "tcx-8-bit")) 168 psdp->descr = "Sun TCX (8bit)"; 169 else 170 psdp->descr = "Sun TCX (S24)"; 171 break; 172 case SBUS_DEVICE_FFB: 173 prop = sparcPromGetProperty(&psdp->node, "name", &len); 174 chiprev = 0; 175 prop = sparcPromGetProperty(&psdp->node, "board_type", &len); 176 if (prop && len == 4) 177 chiprev = *(int *)prop; 178 if (strstr (prop, "afb")) { 179 if (chiprev == 3) 180 psdp->descr = "Sun|Elite3D-M6 Horizontal"; 181 } else { 182 switch (chiprev) { 183 case 0x08: 184 psdp->descr = "Sun FFB 67MHz Creator"; break; 185 case 0x0b: 186 psdp->descr = "Sun FFB 67MHz Creator 3D"; break; 187 case 0x1b: 188 psdp->descr = "Sun FFB 75MHz Creator 3D"; break; 189 case 0x20: 190 case 0x28: 191 psdp->descr = "Sun FFB2 Vertical Creator"; break; 192 case 0x23: 193 case 0x2b: 194 psdp->descr = "Sun FFB2 Vertical Creator 3D"; break; 195 case 0x30: 196 psdp->descr = "Sun FFB2+ Vertical Creator"; break; 197 case 0x33: 198 psdp->descr = "Sun FFB2+ Vertical Creator 3D"; break; 199 case 0x40: 200 case 0x48: 201 psdp->descr = "Sun FFB2 Horizontal Creator"; break; 202 case 0x43: 203 case 0x4b: 204 psdp->descr = "Sun FFB2 Horizontal Creator 3D"; break; 205 } 206 } 207 break; 208 } 209 210 xf86Msg(X_PROBED, "SBUS:(0x%08x) %s", psdp->node.node, psdp->descr); 211 promPath = sparcPromNode2Pathname (&psdp->node); 212 if (promPath) { 213 xf86ErrorF(" at %s", promPath); 214 free(promPath); 215 } 216 } else 217 xf86Msg(X_PROBED, "SBUS: %s", psdp->descr); 218 xf86ErrorF("\n"); 219 } 220 if (useProm) 221 sparcPromClose(); 222} 223 224/* 225 * Parse a BUS ID string, and return the SBUS bus parameters if it was 226 * in the correct format for a SBUS bus id. 227 */ 228 229Bool 230xf86ParseSbusBusString(const char *busID, int *fbNum) 231{ 232 /* 233 * The format is assumed to be one of: 234 * "fbN", e.g. "fb1", which means the device corresponding to /dev/fbN 235 * "nameN", e.g. "cgsix0", which means Nth instance of card NAME 236 * "/prompath", e.g. "/sbus@0,10001000/cgsix@3,0" which is PROM pathname 237 * to the device. 238 */ 239 240 const char *id; 241 int i, len; 242 243 if (StringToBusType(busID, &id) != BUS_SBUS) 244 return FALSE; 245 246 if (*id != '/') { 247 if (!strncmp (id, "fb", 2)) { 248 if (!isdigit(id[2])) 249 return FALSE; 250 *fbNum = atoi(id + 2); 251 return TRUE; 252 } else { 253 sbusDevicePtr *psdpp; 254 int devId; 255 256 for (i = 0, len = 0; sbusDeviceTable[i].devId; i++) { 257 len = strlen(sbusDeviceTable[i].promName); 258 if (!strncmp (sbusDeviceTable[i].promName, id, len) 259 && isdigit(id[len])) 260 break; 261 } 262 devId = sbusDeviceTable[i].devId; 263 if (!devId) return FALSE; 264 i = atoi(id + len); 265 for (psdpp = xf86SbusInfo; *psdpp; ++psdpp) { 266 if ((*psdpp)->devId != devId) 267 continue; 268 if (!i) { 269 *fbNum = (*psdpp)->fbNum; 270 return TRUE; 271 } 272 i--; 273 } 274 } 275 return FALSE; 276 } 277 278 if (sparcPromInit() >= 0) { 279 i = sparcPromPathname2Node(id); 280 sparcPromClose(); 281 if (i) { 282 sbusDevicePtr *psdpp; 283 for (psdpp = xf86SbusInfo; *psdpp; ++psdpp) { 284 if ((*psdpp)->node.node == i) { 285 *fbNum = (*psdpp)->fbNum; 286 return TRUE; 287 } 288 } 289 } 290 } 291 return FALSE; 292} 293 294/* 295 * Compare a BUS ID string with a SBUS bus id. Return TRUE if they match. 296 */ 297 298Bool 299xf86CompareSbusBusString(const char *busID, int fbNum) 300{ 301 int iFbNum; 302 303 if (xf86ParseSbusBusString(busID, &iFbNum)) { 304 return fbNum == iFbNum; 305 } else { 306 return FALSE; 307 } 308} 309 310/* 311 * Check if the slot requested is free. If it is already in use, return FALSE. 312 */ 313 314Bool 315xf86CheckSbusSlot(int fbNum) 316{ 317 int i; 318 EntityPtr p; 319 320 for (i = 0; i < xf86NumEntities; i++) { 321 p = xf86Entities[i]; 322 /* Check if this SBUS slot is taken */ 323 if (p->bus.type == BUS_SBUS && p->bus.id.sbus.fbNum == fbNum) 324 return FALSE; 325 } 326 327 return TRUE; 328} 329 330/* 331 * If the slot requested is already in use, return -1. 332 * Otherwise, claim the slot for the screen requesting it. 333 */ 334 335int 336xf86ClaimSbusSlot(sbusDevicePtr psdp, DriverPtr drvp, 337 GDevPtr dev, Bool active) 338{ 339 EntityPtr p = NULL; 340 341 int num; 342 343 if (xf86CheckSbusSlot(psdp->fbNum)) { 344 num = xf86AllocateEntity(); 345 p = xf86Entities[num]; 346 p->driver = drvp; 347 p->chipset = -1; 348 p->bus.type = BUS_SBUS; 349 xf86AddDevToEntity(num, dev); 350 p->bus.id.sbus.fbNum = psdp->fbNum; 351 p->active = active; 352 p->inUse = FALSE; 353 sbusSlotClaimed = TRUE; 354 return num; 355 } else 356 return -1; 357} 358 359int 360xf86MatchSbusInstances(const char *driverName, int sbusDevId, 361 GDevPtr *devList, int numDevs, DriverPtr drvp, 362 int **foundEntities) 363{ 364 int i,j; 365 sbusDevicePtr psdp, *psdpp; 366 int numClaimedInstances = 0; 367 int allocatedInstances = 0; 368 int numFound = 0; 369 GDevPtr devBus = NULL; 370 GDevPtr dev = NULL; 371 int *retEntities = NULL; 372 int useProm = 0; 373 374 struct Inst { 375 sbusDevicePtr sbus; 376 GDevPtr dev; 377 Bool claimed; /* BusID matches with a device section */ 378 } *instances = NULL; 379 380 *foundEntities = NULL; 381 for (psdpp = xf86SbusInfo, psdp = *psdpp; psdp; psdp = *++psdpp) { 382 if (psdp->devId != sbusDevId) 383 continue; 384 if (psdp->fd == -2) 385 continue; 386 ++allocatedInstances; 387 instances = xnfrealloc(instances, 388 allocatedInstances * sizeof(struct Inst)); 389 instances[allocatedInstances - 1].sbus = psdp; 390 instances[allocatedInstances - 1].dev = NULL; 391 instances[allocatedInstances - 1].claimed = FALSE; 392 numFound++; 393 } 394 395 /* 396 * This may be debatable, but if no SBUS devices with a matching vendor 397 * type is found, return zero now. It is probably not desirable to 398 * allow the config file to override this. 399 */ 400 if (allocatedInstances <= 0) { 401 free(instances); 402 return 0; 403 } 404 405 if (sparcPromInit() >= 0) 406 useProm = 1; 407 408 if (xf86DoConfigure && xf86DoConfigurePass1) { 409 GDevPtr pGDev; 410 int actualcards = 0; 411 for (i = 0; i < allocatedInstances; i++) { 412 actualcards++; 413 pGDev = xf86AddBusDeviceToConfigure(drvp->driverName, BUS_SBUS, 414 instances[i].sbus, -1); 415 if (pGDev) { 416 /* 417 * XF86Match???Instances() treat chipID and chipRev as 418 * overrides, so clobber them here. 419 */ 420 pGDev->chipID = pGDev->chipRev = -1; 421 } 422 } 423 free(instances); 424 if (useProm) 425 sparcPromClose(); 426 return actualcards; 427 } 428 429 DebugF("%s instances found: %d\n", driverName, allocatedInstances); 430 431 for (i = 0; i < allocatedInstances; i++) { 432 char *promPath = NULL; 433 434 psdp = instances[i].sbus; 435 devBus = NULL; 436 dev = NULL; 437 if (useProm && psdp->node.node) 438 promPath = sparcPromNode2Pathname(&psdp->node); 439 440 for (j = 0; j < numDevs; j++) { 441 if (devList[j]->busID && *devList[j]->busID) { 442 if (xf86CompareSbusBusString(devList[j]->busID, psdp->fbNum)) { 443 if (devBus) 444 xf86MsgVerb(X_WARNING,0, 445 "%s: More than one matching Device section for " 446 "instance (BusID: %s) found: %s\n", 447 driverName,devList[j]->identifier, 448 devList[j]->busID); 449 else 450 devBus = devList[j]; 451 } 452 } else { 453 if (!dev && !devBus) { 454 if (promPath) 455 xf86Msg(X_PROBED, "Assigning device section with no busID to SBUS:%s\n", 456 promPath); 457 else 458 xf86Msg(X_PROBED, "Assigning device section with no busID to SBUS:fb%d\n", 459 psdp->fbNum); 460 dev = devList[j]; 461 } else 462 xf86MsgVerb(X_WARNING, 0, 463 "%s: More than one matching Device section " 464 "found: %s\n", driverName, devList[j]->identifier); 465 } 466 } 467 if (devBus) dev = devBus; /* busID preferred */ 468 if (!dev && psdp->fd != -2) { 469 if (promPath) { 470 xf86MsgVerb(X_WARNING, 0, "%s: No matching Device section " 471 "for instance (BusID SBUS:%s) found\n", 472 driverName, promPath); 473 } else 474 xf86MsgVerb(X_WARNING, 0, "%s: No matching Device section " 475 "for instance (BusID SBUS:fb%d) found\n", 476 driverName, psdp->fbNum); 477 } else if (dev) { 478 numClaimedInstances++; 479 instances[i].claimed = TRUE; 480 instances[i].dev = dev; 481 } 482 free(promPath); 483 } 484 485 DebugF("%s instances found: %d\n", driverName, numClaimedInstances); 486 487 /* 488 * Of the claimed instances, check that another driver hasn't already 489 * claimed its slot. 490 */ 491 numFound = 0; 492 for (i = 0; i < allocatedInstances && numClaimedInstances > 0; i++) { 493 if (!instances[i].claimed) 494 continue; 495 psdp = instances[i].sbus; 496 if (!xf86CheckSbusSlot(psdp->fbNum)) 497 continue; 498 499 DebugF("%s: card at fb%d %08x is claimed by a Device section\n", 500 driverName, psdp->fbNum, psdp->node.node); 501 502 /* Allocate an entry in the lists to be returned */ 503 numFound++; 504 retEntities = xnfrealloc(retEntities, numFound * sizeof(int)); 505 retEntities[numFound - 1] 506 = xf86ClaimSbusSlot(psdp, drvp, instances[i].dev,instances[i].dev->active ? 507 TRUE : FALSE); 508 } 509 free(instances); 510 if (numFound > 0) { 511 *foundEntities = retEntities; 512 } 513 514 if (useProm) 515 sparcPromClose(); 516 517 return numFound; 518} 519 520/* 521 * xf86GetSbusInfoForEntity() -- Get the sbusDevicePtr of entity. 522 */ 523sbusDevicePtr 524xf86GetSbusInfoForEntity(int entityIndex) 525{ 526 sbusDevicePtr *psdpp; 527 EntityPtr p = xf86Entities[entityIndex]; 528 529 if (entityIndex >= xf86NumEntities 530 || p->bus.type != BUS_SBUS) return NULL; 531 532 for (psdpp = xf86SbusInfo; *psdpp != NULL; psdpp++) { 533 if (p->bus.id.sbus.fbNum == (*psdpp)->fbNum) 534 return *psdpp; 535 } 536 return NULL; 537} 538 539int 540xf86GetEntityForSbusInfo(sbusDevicePtr psdp) 541{ 542 int i; 543 544 for (i = 0; i < xf86NumEntities; i++) { 545 EntityPtr p = xf86Entities[i]; 546 if (p->bus.type != BUS_SBUS) continue; 547 548 if (p->bus.id.sbus.fbNum == psdp->fbNum) 549 return i; 550 } 551 return -1; 552} 553 554void 555xf86SbusUseBuiltinMode(ScrnInfoPtr pScrn, sbusDevicePtr psdp) 556{ 557 DisplayModePtr mode; 558 559 mode = xnfcalloc(sizeof(DisplayModeRec), 1); 560 mode->name = "current"; 561 mode->next = mode; 562 mode->prev = mode; 563 mode->type = M_T_BUILTIN; 564 mode->Clock = 100000000; 565 mode->HDisplay = psdp->width; 566 mode->HSyncStart = psdp->width; 567 mode->HSyncEnd = psdp->width; 568 mode->HTotal = psdp->width; 569 mode->VDisplay = psdp->height; 570 mode->VSyncStart = psdp->height; 571 mode->VSyncEnd = psdp->height; 572 mode->VTotal = psdp->height; 573 mode->SynthClock = mode->Clock; 574 mode->CrtcHDisplay = mode->HDisplay; 575 mode->CrtcHSyncStart = mode->HSyncStart; 576 mode->CrtcHSyncEnd = mode->HSyncEnd; 577 mode->CrtcHTotal = mode->HTotal; 578 mode->CrtcVDisplay = mode->VDisplay; 579 mode->CrtcVSyncStart = mode->VSyncStart; 580 mode->CrtcVSyncEnd = mode->VSyncEnd; 581 mode->CrtcVTotal = mode->VTotal; 582 mode->CrtcHAdjusted = FALSE; 583 mode->CrtcVAdjusted = FALSE; 584 pScrn->modes = mode; 585 pScrn->virtualX = psdp->width; 586 pScrn->virtualY = psdp->height; 587} 588 589static DevPrivateKeyRec sbusPaletteKeyIndex = { .initialized = 0 }; 590static DevPrivateKey sbusPaletteKey = &sbusPaletteKeyIndex; 591typedef struct _sbusCmap { 592 sbusDevicePtr psdp; 593 CloseScreenProcPtr CloseScreen; 594 Bool origCmapValid; 595 unsigned char origRed[16]; 596 unsigned char origGreen[16]; 597 unsigned char origBlue[16]; 598} sbusCmapRec, *sbusCmapPtr; 599 600#define SBUSCMAPPTR(pScreen) ((sbusCmapPtr) \ 601 dixLookupPrivate(&(pScreen)->devPrivates, sbusPaletteKey)) 602 603static void 604xf86SbusCmapLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, 605 LOCO *colors, VisualPtr pVisual) 606{ 607 int i, index, ret; 608 sbusCmapPtr cmap; 609 struct fbcmap fbcmap; 610 unsigned char *data = malloc(numColors*3); 611 612 cmap = SBUSCMAPPTR(pScrn->pScreen); 613 if (!cmap) return; 614 fbcmap.count = 0; 615 fbcmap.index = indices[0]; 616 fbcmap.red = data; 617 fbcmap.green = data + numColors; 618 fbcmap.blue = fbcmap.green + numColors; 619 for (i = 0; i < numColors; i++) { 620 index = indices[i]; 621 if (fbcmap.count && index != fbcmap.index + fbcmap.count) { 622 ret = ioctl (cmap->psdp->fd, FBIOPUTCMAP, &fbcmap); 623 if (ret != 0) 624 xf86Msg(X_ERROR, "%s: ioctl(%d, FBIOPUTCMAP): %d %d\n", 625 __func__, cmap->psdp->fd, ret, errno); 626 fbcmap.count = 0; 627 fbcmap.index = index; 628 } 629 fbcmap.red[fbcmap.count] = colors[index].red; 630 fbcmap.green[fbcmap.count] = colors[index].green; 631 fbcmap.blue[fbcmap.count++] = colors[index].blue; 632 } 633 ret = ioctl (cmap->psdp->fd, FBIOPUTCMAP, &fbcmap); 634 if (ret != 0) 635 xf86Msg(X_ERROR, "%s: ioctl(%d, FBIOPUTCMAP): %d %d\n", __func__, 636 cmap->psdp->fd, ret, errno); 637 free(data); 638} 639 640static Bool 641xf86SbusCmapCloseScreen(int i, ScreenPtr pScreen) 642{ 643 sbusCmapPtr cmap; 644 struct fbcmap fbcmap; 645 646 cmap = SBUSCMAPPTR(pScreen); 647 if (cmap->origCmapValid) { 648 fbcmap.index = 0; 649 fbcmap.count = 16; 650 fbcmap.red = cmap->origRed; 651 fbcmap.green = cmap->origGreen; 652 fbcmap.blue = cmap->origBlue; 653 ioctl (cmap->psdp->fd, FBIOPUTCMAP, &fbcmap); 654 } 655 pScreen->CloseScreen = cmap->CloseScreen; 656 free(cmap); 657 return (*pScreen->CloseScreen) (i, pScreen); 658} 659 660Bool 661xf86SbusHandleColormaps(ScreenPtr pScreen, sbusDevicePtr psdp) 662{ 663 sbusCmapPtr cmap; 664 struct fbcmap fbcmap; 665 int ret; 666 unsigned char data[2]; 667 668 cmap = xnfcalloc(1, sizeof(sbusCmapRec)); 669 if (!dixPrivateKeyRegistered(sbusPaletteKey)) { 670 dixRegisterPrivateKey(sbusPaletteKey, PRIVATE_SCREEN, 0); 671 } 672 dixSetPrivate(&pScreen->devPrivates, sbusPaletteKey, cmap); 673 cmap->psdp = psdp; 674 fbcmap.index = 0; 675 fbcmap.count = 16; 676 fbcmap.red = cmap->origRed; 677 fbcmap.green = cmap->origGreen; 678 fbcmap.blue = cmap->origBlue; 679 if ((ret = ioctl (psdp->fd, FBIOGETCMAP, &fbcmap)) >= 0) 680 cmap->origCmapValid = TRUE; 681 fbcmap.index = 0; 682 fbcmap.count = 2; 683 fbcmap.red = data; 684 fbcmap.green = data; 685 fbcmap.blue = data; 686 if (pScreen->whitePixel == 0) { 687 data[0] = 255; 688 data[1] = 0; 689 } else { 690 data[0] = 0; 691 data[1] = 255; 692 } 693 ret = ioctl (psdp->fd, FBIOPUTCMAP, &fbcmap); 694 if (ret != 0) 695 xf86Msg(X_ERROR, "%s: ioctl(%d, FBIOPUTCMAP): %d %d\n", __func__, 696 psdp->fd, ret, errno); 697 cmap->CloseScreen = pScreen->CloseScreen; 698 pScreen->CloseScreen = xf86SbusCmapCloseScreen; 699 return xf86HandleColormaps(pScreen, 256, 8, 700 xf86SbusCmapLoadPalette, NULL, 0); 701} 702 703Bool 704xf86SbusConfigure(void *busData, sbusDevicePtr sBus) 705{ 706 if (sBus && sBus->fbNum == ((sbusDevicePtr) busData)->fbNum) 707 return 0; 708 return 1; 709} 710 711void 712xf86SbusConfigureNewDev(void *busData, sbusDevicePtr sBus, GDevRec *GDev) 713{ 714 char *promPath = NULL; 715 716 sBus = (sbusDevicePtr) busData; 717 GDev->identifier = sBus->descr; 718 if (sparcPromInit() >= 0) { 719 promPath = sparcPromNode2Pathname(&sBus->node); 720 sparcPromClose(); 721 } 722 if (promPath) { 723 XNFasprintf(&GDev->busID, "SBUS:%s", promPath); 724 free(promPath); 725 } else { 726 XNFasprintf(&GDev->busID, "SBUS:fb%d", sBus->fbNum); 727 } 728} 729