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