diff -Nurb hw/xfree86/common/xf86sbusBus.c hw/xfree86/common/xf86sbusBus.c --- hw/xfree86/common/xf86sbusBus.c 2007-04-28 05:18:54.079208200 +0200 +++ hw/xfree86/common/xf86sbusBus.c 2007-04-28 05:21:12.772747800 +0200 @@ -41,6 +41,11 @@ #include "xf86sbusBus.h" #include "xf86Sbus.h" +#ifdef sun +#include +#include +#endif + Bool sbusSlotClaimed = FALSE; static int xf86nSbusInfo; @@ -49,31 +54,60 @@ CheckSbusDevice(const char *device, int fbNum) { int fd, i; - struct fbgattr fbattr; +/* struct fbgattr fbattr; */ sbusDevicePtr psdp; +#ifdef sun + struct vis_identifier vid; +#endif + + struct fbgattr fbattr; + fd = open(device, O_RDONLY, 0); if (fd < 0) return; + memset(&fbattr, 0, sizeof(fbattr)); + +#ifdef sun + if (ioctl(fd, VIS_GETIDENTIFIER, &vid) >= 0) + { + char *promName; + + for (promName = vid.name; *promName; promName++) + if (((*promName >= 'a') && (*promName <= 'z')) || + ((*promName >= '0') && (*promName <= '9'))) + break; + + for (i = 0; sbusDeviceTable[i].devId; i++) + if (!strcmp(sbusDeviceTable[i].promName, promName)) + break; + } +#else + { if (ioctl(fd, FBIOGATTR, &fbattr) < 0) { if (ioctl(fd, FBIOGTYPE, &fbattr.fbtype) < 0) { close(fd); return; } } - close(fd); + for (i = 0; sbusDeviceTable[i].devId; i++) if (sbusDeviceTable[i].fbType == fbattr.fbtype.fb_type) break; - if (! sbusDeviceTable[i].devId) - return; - xf86SbusInfo = xnfrealloc(xf86SbusInfo, sizeof(psdp) * (++xf86nSbusInfo + 1)); + } +#endif + + close(fd); + if (!sbusDeviceTable[i].devId) return; + xf86nSbusInfo++; + xf86SbusInfo = xnfrealloc(xf86SbusInfo, sizeof(psdp) * (xf86nSbusInfo + 1)); xf86SbusInfo[xf86nSbusInfo] = NULL; - xf86SbusInfo[xf86nSbusInfo - 1] = psdp = xnfcalloc(sizeof (sbusDevice), 1); + xf86SbusInfo[xf86nSbusInfo - 1] = psdp = xnfcalloc(sizeof(sbusDevice), 1); psdp->devId = sbusDeviceTable[i].devId; - psdp->fbNum = fbNum; psdp->device = xnfstrdup(device); + psdp->descr = sbusDeviceTable[i].descr; + psdp->fbNum = fbNum; psdp->width = fbattr.fbtype.fb_width; psdp->height = fbattr.fbtype.fb_height; psdp->fd = -1; @@ -82,24 +116,28 @@ void xf86SbusProbe(void) { - int i, useProm = 0; + int useProm = 0; char fbDevName[32]; sbusDevicePtr psdp, *psdpp; xf86SbusInfo = xalloc(sizeof(psdp)); *xf86SbusInfo = NULL; + + { + int i; + for (i = 0; i < 32; i++) { sprintf(fbDevName, "/dev/fb%d", i); CheckSbusDevice(fbDevName, i); } + } + if (sparcPromInit() >= 0) { useProm = 1; sparcPromAssignNodes(); } + for (psdpp = xf86SbusInfo; (psdp = *psdpp); psdpp++) { - for (i = 0; sbusDeviceTable[i].devId; i++) - if (sbusDeviceTable[i].devId == psdp->devId) - psdp->descr = sbusDeviceTable[i].descr; /* * If we can use PROM information and found the PROM node for this * device, we can tell more about the card. @@ -108,15 +146,29 @@ char *prop, *promPath; int len, chiprev, vmsize; + if (psdp->height <= 0) { + prop = sparcPromGetProperty(&psdp->node, "height", &len); + if (prop && (len == 4)) + psdp->height = *(int *)prop; + } + + if (psdp->width <= 0) { + prop = sparcPromGetProperty(&psdp->node, "width", &len); + if (prop && (len == 4)) + psdp->width = *(int *)prop; + } + switch (psdp->devId) { case SBUS_DEVICE_MGX: prop = sparcPromGetProperty(&psdp->node, "fb_size", &len); if (prop && len == 4 && *(int *)prop == 0x400000) psdp->descr = "Quantum 3D MGXplus with 4M VRAM"; break; + case SBUS_DEVICE_CG6: chiprev = 0; vmsize = 0; + prop = sparcPromGetProperty(&psdp->node, "chiprev", &len); if (prop && len == 4) chiprev = *(int *)prop; @@ -144,6 +196,7 @@ default: psdp->descr = "Sun Turbo GX"; break; } + break; } break; case SBUS_DEVICE_CG14: @@ -170,12 +223,15 @@ psdp->descr = "Sun TCX (S24)"; break; case SBUS_DEVICE_FFB: - prop = sparcPromGetProperty(&psdp->node, "name", &len); chiprev = 0; prop = sparcPromGetProperty(&psdp->node, "board_type", &len); if (prop && len == 4) chiprev = *(int *)prop; - if (strstr (prop, "afb")) { + prop = sparcPromGetProperty(&psdp->node, "name", &len); + if (!prop || (len < 3)) + break; + + if (strstr(prop, "afb")) { if (chiprev == 3) psdp->descr = "Sun|Elite3D-M6 Horizontal"; } else { @@ -205,18 +261,35 @@ } } break; +#ifdef sun + case SBUS_DEVICE_UNK: +/* if (ioctl(fbfd, VIS_GETIDENTIFIER, &visid) >= 0) { + * psdp->descr = strdup(visid.name); + * } else { + */ + psdp->descr = "UNKNOWN SBUS_or_UPA frame buffer"; +/* + * } + */ + break; +#endif + } - xf86Msg(X_PROBED, "SBUS:(0x%08x) %s", psdp->node.node, psdp->descr); promPath = sparcPromNode2Pathname (&psdp->node); if (promPath) { - xf86ErrorF(" at %s", promPath); + xf86Msg(X_PROBED, "SBUS_or_UPA: (0x%08x) %s at %s\n", + psdp->node.node, psdp->descr, promPath); xfree(promPath); + } else { + xf86Msg(X_PROBED, "SBUS_or_UPA: (0x%08x) %s\n", + psdp->node.node, psdp->descr); } - } else - xf86Msg(X_PROBED, "SBUS: %s", psdp->descr); - xf86ErrorF("\n"); + } else { + xf86Msg(X_PROBED, "SBUS_or_UPA: %s\n", psdp->descr); } + } + if (useProm) sparcPromClose(); } @@ -237,30 +310,40 @@ * to the device. */ + sbusDevicePtr *psdpp; const char *id; - int i, len; + int i, len, devId; if (StringToBusType(busID, &id) != BUS_SBUS) return FALSE; + for (psdpp = xf86SbusInfo; *psdpp; ++psdpp) { + if (!strcmp((*psdpp)->device, id)) { + *fbNum = (*psdpp)->fbNum; + return TRUE; + } + } + if (*id != '/') { - if (!strncmp (id, "fb", 2)) { - if (!isdigit(id[2])) - return FALSE; - *fbNum = atoi(id + 2); + for (psdpp = xf86SbusInfo; *psdpp; ++psdpp) { + if (!strcmp((*psdpp)->device + 5, id)) { + *fbNum = (*psdpp)->fbNum; return TRUE; - } else { - sbusDevicePtr *psdpp; - int devId; + } + } - for (i = 0, len = 0; sbusDeviceTable[i].devId; i++) { + len = 0; + for (i = 0; sbusDeviceTable[i].devId; i++) { len = strlen(sbusDeviceTable[i].promName); - if (!strncmp (sbusDeviceTable[i].promName, id, len) - && isdigit(id[len])) + if (!strncmp(sbusDeviceTable[i].promName, id, len) && + isdigit(id[len])) break; } + devId = sbusDeviceTable[i].devId; - if (!devId) return FALSE; + if (!devId) + return FALSE; + i = atoi(id + len); for (psdpp = xf86SbusInfo; *psdpp; ++psdpp) { if ((*psdpp)->devId != devId) @@ -269,9 +352,9 @@ *fbNum = (*psdpp)->fbNum; return TRUE; } + i--; } - } return FALSE; } @@ -280,6 +363,7 @@ sparcPromClose(); if (i) { sbusDevicePtr *psdpp; + for (psdpp = xf86SbusInfo; *psdpp; ++psdpp) { if ((*psdpp)->node.node == i) { *fbNum = (*psdpp)->fbNum; @@ -288,6 +372,7 @@ } } } + return FALSE; } @@ -300,11 +385,9 @@ { int iFbNum; - if (xf86ParseSbusBusString(busID, &iFbNum)) { - return fbNum == iFbNum; - } else { + if (xf86ParseSbusBusString(busID, &iFbNum) && (fbNum == iFbNum)) + return TRUE; return FALSE; - } } /* @@ -320,7 +403,7 @@ for (i = 0; i < xf86NumEntities; i++) { p = xf86Entities[i]; /* Check if this SBUS slot is taken */ - if (p->busType == BUS_SBUS && p->sbusBusId.fbNum == fbNum) + if ((p->busType == BUS_SBUS) && (p->sbusBusId.fbNum == fbNum)) return FALSE; } @@ -340,7 +423,9 @@ int num; - if (xf86CheckSbusSlot(psdp->fbNum)) { + if (!xf86CheckSbusSlot(psdp->fbNum)) + return -1; + num = xf86AllocateEntity(); p = xf86Entities[num]; p->driver = drvp; @@ -351,16 +436,14 @@ p->active = active; p->inUse = FALSE; /* Here we initialize the access structure */ - p->access = xnfcalloc(1,sizeof(EntityAccessRec)); + p->access = xnfcalloc(1, sizeof(EntityAccessRec)); p->access->fallback = &AccessNULL; p->access->pAccess = &AccessNULL; sbusSlotClaimed = TRUE; return num; - } else - return -1; } -_X_EXPORT int +/* _X_EXPORT */ int xf86MatchSbusInstances(const char *driverName, int sbusDevId, GDevPtr *devList, int numDevs, DriverPtr drvp, int **foundEntities) @@ -382,7 +465,7 @@ } *instances = NULL; *foundEntities = NULL; - for (psdpp = xf86SbusInfo, psdp = *psdpp; psdp; psdp = *++psdpp) { + for (psdpp = xf86SbusInfo; (psdp = *psdpp); psdpp++) { if (psdp->devId != sbusDevId) continue; if (psdp->fd == -2) @@ -463,27 +546,29 @@ } else { if (!dev && !devBus) { if (promPath) - xf86Msg(X_PROBED, "Assigning device section with no busID to SBUS:%s\n", + xf86Msg(X_PROBED, "Assigning device section with no busID to SBUS_or_UPA:%s\n", promPath); else - xf86Msg(X_PROBED, "Assigning device section with no busID to SBUS:fb%d\n", - psdp->fbNum); + xf86Msg(X_PROBED, "Assigning device section with no" + " busID to SBUS_or_UPA:fb%d\n", psdp->fbNum); dev = devList[j]; - } else + } else { xf86MsgVerb(X_WARNING, 0, - "%s: More than one matching Device section " - "found: %s\n", driverName, devList[j]->identifier); + "%s: More than one matching Device section found: %s\n", + driverName, devList[j]->identifier); + } } } + if (devBus) dev = devBus; /* busID preferred */ if (!dev && psdp->fd != -2) { if (promPath) { xf86MsgVerb(X_WARNING, 0, "%s: No matching Device section " - "for instance (BusID SBUS:%s) found\n", + "for instance (BusID SBUS_or_UPA:%s) found\n", driverName, promPath); } else xf86MsgVerb(X_WARNING, 0, "%s: No matching Device section " - "for instance (BusID SBUS:fb%d) found\n", + "for instance (BusID SBUS_or_UPA:fb%d) found\n", driverName, psdp->fbNum); } else if (dev) { numClaimedInstances++; @@ -503,7 +588,8 @@ * claimed its slot. */ numFound = 0; - for (i = 0; i < allocatedInstances && numClaimedInstances > 0; i++) { + if (numClaimedInstances > 0) { + for (i = 0; i < allocatedInstances; i++) { if (!instances[i].claimed) continue; psdp = instances[i].sbus; @@ -522,10 +608,10 @@ = xf86ClaimSbusSlot(psdp, drvp, instances[i].dev,instances[i].dev->active ? TRUE : FALSE); } + } xfree(instances); - if (numFound > 0) { + if (numFound > 0) *foundEntities = retEntities; - } if (useProm) sparcPromClose(); @@ -536,38 +622,41 @@ /* * xf86GetSbusInfoForEntity() -- Get the sbusDevicePtr of entity. */ -_X_EXPORT sbusDevicePtr + +/* _X_EXPORT */ sbusDevicePtr xf86GetSbusInfoForEntity(int entityIndex) { sbusDevicePtr *psdpp; - EntityPtr p = xf86Entities[entityIndex]; + EntityPtr p; - if (entityIndex >= xf86NumEntities - || p->busType != BUS_SBUS) return NULL; + if ((entityIndex <= -1) || (entityIndex >= xf86NumEntities) || (xf86SbusInfo == NULL)) return NULL; + p = xf86Entities[entityIndex]; + if (p->busType != BUS_SBUS) + return NULL; - for (psdpp = xf86SbusInfo; *psdpp != NULL; psdpp++) { + for (psdpp = xf86SbusInfo; *psdpp; psdpp++) { if (p->sbusBusId.fbNum == (*psdpp)->fbNum) return (*psdpp); } return NULL; } -_X_EXPORT int +/* _X_EXPORT */ int xf86GetEntityForSbusInfo(sbusDevicePtr psdp) { int i; for (i = 0; i < xf86NumEntities; i++) { EntityPtr p = xf86Entities[i]; - if (p->busType != BUS_SBUS) continue; + if (p->busType != BUS_SBUS) continue; if (p->sbusBusId.fbNum == psdp->fbNum) return i; } return -1; } -_X_EXPORT void +/* _X_EXPORT */ void xf86SbusUseBuiltinMode(ScrnInfoPtr pScrn, sbusDevicePtr psdp) { DisplayModePtr mode; @@ -613,7 +702,7 @@ unsigned char origBlue[16]; } sbusCmapRec, *sbusCmapPtr; -#define SBUSCMAPPTR(pScreen) ((sbusCmapPtr)((pScreen)->devPrivates[sbusPaletteIndex].ptr)) +#define SBUSCMAPPTR(pScreen) (pScreen)->devPrivates[sbusPaletteIndex].ptr static void xf86SbusCmapLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, @@ -666,7 +755,7 @@ return (*pScreen->CloseScreen) (i, pScreen); } -_X_EXPORT Bool +/* _X_EXPORT Bool */ Bool xf86SbusHandleColormaps(ScreenPtr pScreen, sbusDevicePtr psdp) { sbusCmapPtr cmap; @@ -679,7 +768,7 @@ sbusPaletteGeneration = serverGeneration; } cmap = xnfcalloc(1, sizeof(sbusCmapRec)); - pScreen->devPrivates[sbusPaletteIndex].ptr = cmap; + SBUSCMAPPTR(pScreen) = cmap; cmap->psdp = psdp; fbcmap.index = 0; fbcmap.count = 16; @@ -693,6 +782,7 @@ fbcmap.red = data; fbcmap.green = data; fbcmap.blue = data; + if (pScreen->whitePixel == 0) { data[0] = 255; data[1] = 0; diff -Nurb hw/xfree86/common/xf86sbusBus.h hw/xfree86/common/xf86sbusBus.h --- hw/xfree86/common/xf86sbusBus.h 2007-04-28 05:19:02.954183600 +0200 +++ hw/xfree86/common/xf86sbusBus.h 2007-04-28 05:21:24.289598000 +0200 @@ -39,6 +39,7 @@ #define SBUS_DEVICE_FFB 0x000b #define SBUS_DEVICE_GT 0x000c #define SBUS_DEVICE_MGX 0x000d +#define SBUS_DEVICE_UNK 0x000e typedef struct sbus_prom_node { int node; @@ -46,6 +47,11 @@ int cookie[2]; } sbusPromNode, *sbusPromNodePtr; +typedef struct sbusupa_obp_parent { + sbusPromNode node; + struct sbusupa_obp_parent *parent; +} sbusupaObpParent, *sbusupaObpParentPtr; + typedef struct sbus_device { int devId; int fbNum; @@ -54,6 +60,9 @@ sbusPromNode node; char *descr; char *device; + sbusupaObpParentPtr parent; + void *OSprivate; + int mmapCount; } sbusDevice, *sbusDevicePtr; extern struct sbus_devtable { @@ -63,29 +72,30 @@ char *descr; } sbusDeviceTable[]; + void xf86SbusProbe(void); extern sbusDevicePtr *xf86SbusInfo; - -int xf86MatchSbusInstances(const char *driverName, int sbusDevId, - GDevPtr *devList, int numDevs, DriverPtr drvp, - int **foundEntities); +Bool xf86ParseSbusBusString(const char *busID, int *fbNum); +Bool xf86CompareSbusBusString(const char *busID, int fbNum); +Bool xf86CheckSbusSlot(int fbNum); +int xf86ClaimSbusSlot(sbusDevicePtr psdp, DriverPtr drvp, GDevPtr dev, Bool active); +int xf86MatchSbusInstances(const char *driverName, int sbusDevId, GDevPtr *devList, + int numDevs, DriverPtr drvp, int **foundEntities); sbusDevicePtr xf86GetSbusInfoForEntity(int entityIndex); int xf86GetEntityForSbusInfo(sbusDevicePtr psdp); void xf86SbusUseBuiltinMode(ScrnInfoPtr pScrn, sbusDevicePtr psdp); -pointer xf86MapSbusMem(sbusDevicePtr psdp, unsigned long offset, - unsigned long size); +Bool xf86ExploreSbusUpaMemorySpace(sbusDevicePtr psdp, char **devName, unsigned int *devOffset, + unsigned int *fbSize, unsigned int *fbOffset, unsigned int *flags); +pointer xf86MapSbusMem(sbusDevicePtr psdp, unsigned long offset, unsigned long size); void xf86UnmapSbusMem(sbusDevicePtr psdp, pointer addr, unsigned long size); void xf86SbusHideOsHwCursor(sbusDevicePtr psdp); void xf86SbusSetOsHwCursorCmap(sbusDevicePtr psdp, int bg, int fg); Bool xf86SbusHandleColormaps(ScreenPtr pScreen, sbusDevicePtr psdp); - extern int promRootNode; - int promGetSibling(int node); int promGetChild(int node); char * promGetProperty(const char *prop, int *lenp); int promGetBool(const char *prop); - int sparcPromInit(void); void sparcPromClose(void); char * sparcPromGetProperty(sbusPromNodePtr pnode, const char *prop, int *lenp); diff -Nurb hw/xfree86/os-support/bus/Sbus.c hw/xfree86/os-support/bus/Sbus.c --- hw/xfree86/os-support/bus/Sbus.c 2007-04-28 05:16:33.198927800 +0200 +++ hw/xfree86/os-support/bus/Sbus.c 2007-04-28 05:19:50.074442000 +0200 @@ -44,11 +44,11 @@ int promRootNode; static int promFd = -1; -static int promCurrentNode; static int promOpenCount = 0; static int promP1275 = -1; #define MAX_PROP 128 #define MAX_VAL (4096-128-4) + static struct openpromio *promOpio; sbusDevicePtr *xf86SbusInfo = NULL; @@ -68,32 +68,34 @@ { SBUS_DEVICE_TCX, FBTYPE_TCXCOLOR, "tcx", "Sun TCX" }, { SBUS_DEVICE_FFB, FBTYPE_CREATOR, "ffb", "Sun FFB" }, { SBUS_DEVICE_FFB, FBTYPE_CREATOR, "afb", "Sun Elite3D" }, - { 0, 0, NULL } + { SBUS_DEVICE_FFB, FBTYPE_CREATOR, "gfb", "Sun FFB3 XVR-1000" }, + { SBUS_DEVICE_UNK, FBTYPE_LASTPLUSONE + 1, "unknown", "Unknown FB" }, + { 0, 0, NULL, NULL } }; int promGetSibling(int node) { - promOpio->oprom_size = sizeof(int); - if (node == -1) return 0; + + promOpio->oprom_size = sizeof(int); *(int *)promOpio->oprom_array = node; if (ioctl(promFd, OPROMNEXT, promOpio) < 0) return 0; - promCurrentNode = *(int *)promOpio->oprom_array; + return *(int *)promOpio->oprom_array; } int promGetChild(int node) { - promOpio->oprom_size = sizeof(int); - if (!node || node == -1) return 0; + + promOpio->oprom_size = sizeof(int); *(int *)promOpio->oprom_array = node; if (ioctl(promFd, OPROMCHILD, promOpio) < 0) return 0; - promCurrentNode = *(int *)promOpio->oprom_array; + return *(int *)promOpio->oprom_array; } @@ -104,7 +106,8 @@ strcpy(promOpio->oprom_array, prop); if (ioctl(promFd, OPROMGETPROP, promOpio) < 0) - return 0; + return NULL; /* return 0; */ + if (lenp) *lenp = promOpio->oprom_size; return promOpio->oprom_array; } @@ -131,6 +134,7 @@ #define PROM_NODE_SBUS 0x04 #define PROM_NODE_EBUS 0x08 #define PROM_NODE_PCI 0x10 +#define PROM_NODE_UNK 0x20 static int promSetNode(sbusPromNodePtr pnode) @@ -157,11 +161,11 @@ if (promP1275 != -1) return; - promP1275 = 0; + promP1275 = (FALSE || 0); f = fopen("/proc/cpuinfo","r"); if (!f) return; while (fgets(buffer, 1024, f) != NULL) - if (!strncmp (buffer, "type", 4) && strstr (buffer, "sun4u")) { + if (!strncmp(buffer, "type", 4) && (strstr(buffer, "sun4u") || strstr(buffer, "sun4v"))) { promP1275 = 1; break; } @@ -169,7 +173,10 @@ #elif defined(sun) struct utsname buffer; - if ((uname(&buffer) >= 0) && !strcmp(buffer.machine, "sun4u")) + if (promP1275 != -1) + return; + + if ((uname(&buffer) >= 0) && (!strcmp(buffer.machine, "sun4u") || !strcmp(buffer.machine, "sun4v"))) promP1275 = TRUE; else promP1275 = FALSE; @@ -180,7 +187,7 @@ #endif } -_X_EXPORT void +/* _X_EXPORT */ void sparcPromClose(void) { if (promOpenCount > 1) { @@ -198,21 +205,25 @@ promOpenCount = 0; } -_X_EXPORT int +/* _X_EXPORT */ int sparcPromInit(void) { if (promOpenCount) { promOpenCount++; return 0; } + if (promFd <= -1) { promFd = open("/dev/openprom", O_RDONLY, 0); if (promFd == -1) return -1; + } + if (!promOpio) { promOpio = (struct openpromio *)xalloc(4096); if (!promOpio) { sparcPromClose(); return -1; } + } promRootNode = promGetSibling(0); if (!promRootNode) { sparcPromClose(); @@ -224,7 +235,7 @@ return 0; } -_X_EXPORT char * +/* _X_EXPORT */ char * sparcPromGetProperty(sbusPromNodePtr pnode, const char *prop, int *lenp) { if (promSetNode(pnode)) @@ -232,7 +243,7 @@ return promGetProperty(prop, lenp); } -_X_EXPORT int +/* _X_EXPORT */ int sparcPromGetBool(sbusPromNodePtr pnode, const char *prop) { if (promSetNode(pnode)) @@ -241,28 +252,36 @@ } static void -promWalkAssignNodes(int node, int oldnode, int flags, sbusDevicePtr *devicePtrs) +promWalkAssignNodes(sbusPromNode *pCurrent, sbusupaObpParentPtr pParent, sbusDevicePtr *devicePtrs) { - int nextnode; - int len, sbus = flags & PROM_NODE_SBUS; + int len, sbus; char *prop; int devId, i, j; - sbusPromNode pNode, pNode2; + sbusPromNode Node, Node2, newNode; + sbusupaObpParentPtr Parent, Parent2; + newNode = *pCurrent; + sbus = newNode.cookie[0] & PROM_NODE_SBUS; prop = promGetProperty("device_type", &len); - if (prop && (len > 0)) do { - if (!strcmp(prop, "display")) { + do { + if (!prop || (len < 7) || (len > 8) || strcmp(prop, "display")) + break; + prop = promGetProperty("name", &len); if (!prop || len <= 0) break; - while ((*prop >= 'A' && *prop <= 'Z') || *prop == ',') + + while (((*prop >= 'A') && (*prop <= 'Z')) || (*prop == ',')) prop++; + for (i = 0; sbusDeviceTable[i].devId; i++) if (!strcmp(prop, sbusDeviceTable[i].promName)) break; + devId = sbusDeviceTable[i].devId; if (!devId) break; + if (!sbus) { if (devId == SBUS_DEVICE_FFB) { /* @@ -270,56 +289,83 @@ * /SUNW,afb outside of SBUS tree in Linux. */ if (!strcmp(prop, "afb")) - flags |= PROM_NODE_PREF; + newNode.cookie[0] |= PROM_NODE_PREF; } else if (devId != SBUS_DEVICE_CG14) break; } + for (i = 0; i < 32; i++) { if (!devicePtrs[i] || devicePtrs[i]->devId != devId) continue; + if (devicePtrs[i]->node.node) { if ((devicePtrs[i]->node.cookie[0] & ~PROM_NODE_SIBLING) <= - (flags & ~PROM_NODE_SIBLING)) + (newNode.cookie[0] & ~PROM_NODE_SIBLING)) continue; - for (j = i + 1, pNode = devicePtrs[i]->node; j < 32; j++) { - if (!devicePtrs[j] || devicePtrs[j]->devId != devId) + + Node = devicePtrs[i]->node; + Parent = devicePtrs[i]->parent; + for (j = i; ++j < 32; ) { + if (!devicePtrs[j] || (devicePtrs[j]->devId != devId)) continue; - pNode2 = devicePtrs[j]->node; - devicePtrs[j]->node = pNode; - pNode = pNode2; - } + + Node2 = devicePtrs[j]->node; + Parent2 = devicePtrs[j]->parent; + devicePtrs[j]->node = Node; + devicePtrs[j]->parent = Parent; + Node = Node2; + Parent = Parent2; } - devicePtrs[i]->node.node = node; - devicePtrs[i]->node.cookie[0] = flags; - devicePtrs[i]->node.cookie[1] = oldnode; - break; } + devicePtrs[i]->node = newNode; + devicePtrs[i]->parent = pParent; + + for (Parent = pParent; + Parent && (Parent->node.cookie[0] & PROM_NODE_UNK); + Parent = Parent->parent) + Parent->node.cookie[0] &= ~PROM_NODE_UNK; break; } } while (0); prop = promGetProperty("name", &len); - if (prop && len > 0) { - if (!strcmp(prop, "sbus") || !strcmp(prop, "sbi")) + if (prop && (len >= 3) && (len <= 5) && + (!strcmp(prop, "sbus") || !strcmp(prop, "sbi"))) sbus = PROM_NODE_SBUS; + + newNode.cookie[1] = newNode.node; + if ((newNode.node = promGetChild(newNode.cookie[1]))) { + newNode.cookie[0] = sbus; + + Parent = xnfalloc(sizeof(*Parent)); + Parent->node = *pCurrent; + Parent->node.cookie[0] |= PROM_NODE_UNK; + Parent->parent = pParent; + + promWalkAssignNodes(&newNode, Parent, devicePtrs); + + if (Parent->node.cookie[0] & PROM_NODE_UNK) + xfree(Parent); } - nextnode = promGetChild(node); - if (nextnode) - promWalkAssignNodes(nextnode, node, sbus, devicePtrs); + if ((newNode.node = promGetSibling(newNode.cookie[1]))) { + newNode.cookie[0] = sbus | PROM_NODE_SIBLING; - nextnode = promGetSibling(node); - if (nextnode) - promWalkAssignNodes(nextnode, node, PROM_NODE_SIBLING | sbus, devicePtrs); + promWalkAssignNodes(&newNode, pParent, devicePtrs); + } } void sparcPromAssignNodes(void) { sbusDevicePtr psdp, *psdpp; + sbusDevicePtr devicePtrs[32]; + sbusPromNode root; + +#if defined(linux) + int n, holes = 0, i, j; FILE *f; - sbusDevicePtr devicePtrs[32]; (void)memset(devicePtrs, 0, sizeof(devicePtrs)); for (psdpp = xf86SbusInfo, n = 0; (psdp = *psdpp); psdpp++, n++) { @@ -327,6 +373,7 @@ holes = 1; devicePtrs[psdp->fbNum] = psdp; } + if (holes && (f = fopen("/proc/fb", "r")) != NULL) { /* We could not open one of fb devices, check /proc/fb to see what * were the types of the cards missed. */ @@ -335,6 +382,7 @@ static struct { int devId; char *prefix; + char *descr; } procFbPrefixes[] = { { SBUS_DEVICE_BW2, "BWtwo" }, { SBUS_DEVICE_CG14, "CGfourteen" }, @@ -342,9 +390,10 @@ { SBUS_DEVICE_CG3, "CGthree" }, { SBUS_DEVICE_FFB, "Creator" }, { SBUS_DEVICE_FFB, "Elite 3D" }, + { SBUS_DEVICE_FFB, "FFB3 XVR-1000" }, { SBUS_DEVICE_LEO, "Leo" }, { SBUS_DEVICE_TCX, "TCX" }, - { 0, NULL }, + { 0, NULL, NULL }, }; while (fscanf(f, "%d %63s\n", &fbNum, buffer) == 2) { @@ -352,34 +401,35 @@ if (! strncmp(procFbPrefixes[i].prefix, buffer, strlen(procFbPrefixes[i].prefix))) break; + devId = procFbPrefixes[i].devId; - if (! devId) continue; + if (!devId) continue; if (devicePtrs[fbNum]) { if (devicePtrs[fbNum]->devId != devId) xf86ErrorF("Inconsistent /proc/fb with FBIOGATTR\n"); - } else if (!devicePtrs[fbNum]) { - devicePtrs[fbNum] = psdp = xnfcalloc(sizeof (sbusDevice), 1); + } else { devicePtrs[fbNum] = psdp = xnfcalloc(sizeof(sbusDevice), 1); psdp->devId = devId; psdp->fbNum = fbNum; psdp->fd = -2; + psdp->descr = procFbPrefixes[i].descr; } } + fclose(f); } - promGetSibling(0); - promWalkAssignNodes(promRootNode, 0, PROM_NODE_PREF, devicePtrs); - for (i = 0, j = 0; i < 32; i++) - if (devicePtrs[i] && devicePtrs[i]->fbNum == -1) - j++; - xf86SbusInfo = xnfrealloc(xf86SbusInfo, sizeof(psdp) * (n + j + 1)); - for (i = 0, psdpp = xf86SbusInfo; i < 32; i++) - if (devicePtrs[i]) { - if (devicePtrs[i]->fbNum == -1) { - memmove(psdpp + 1, psdpp, sizeof(psdpp) * (n + 1)); - *psdpp = devicePtrs[i]; - } else - n--; - } + +#else + + (void)memset(devicePtrs, 0, sizeof(devicePtrs)); + for (psdpp = xf86SbusInfo; (psdp = *psdpp); psdpp++) + devicePtrs[psdp->fbNum] = psdp; + +#endif + + root.node = promGetSibling(0); + root.cookie[0] = PROM_NODE_SIBLING | PROM_NODE_PREF; + root.cookie[1] = 0; + promWalkAssignNodes(&root, NULL, devicePtrs); } static char * @@ -393,6 +443,7 @@ prop = promGetProperty("reg", &len); if (prop && len >= 4) { unsigned int *reg = (unsigned int *)prop; + if (!promP1275 || (type == PROM_NODE_SBUS) || (type == PROM_NODE_EBUS)) sprintf (regstr, "@%x,%x", reg[0], reg[1]); else if (type == PROM_NODE_PCI) { @@ -418,6 +469,7 @@ sprintf (regstr, "@%x,%x", regs[0] >> 4, regs[1]); } } + return regstr; } @@ -461,12 +513,14 @@ char *ret; if (!pnode->node) return NULL; + ret = xalloc(4096); if (!ret) return NULL; + if (promWalkNode2Pathname(ret, promRootNode, promGetChild(promRootNode), pnode->node, 0)) return ret; xfree(ret); - return NULL; +return NULL; } static int @@ -555,34 +609,73 @@ return i; } -_X_EXPORT pointer +Bool +xf86ExploreSbusUpaMemorySpace(sbusDevicePtr psdp, char **devName, + unsigned int *devOffset, unsigned int *fbSize, + unsigned int *fbOffset, unsigned int *flags) +{ + /* Check offsets for being 32 bits */ + unsigned int offset; + + if (!psdp || !devOffset || devOffset[1]) + return FALSE; + offset = devOffset[0]; + if (fbOffset) { + if ((offset ^ (unsigned int)(-1L)) < *fbOffset) + return FALSE; + offset += *fbOffset; + } + if (fbSize) { + if ((offset ^ (unsigned int)(-1L)) < *fbSize) + return FALSE; + } + if (devName) *devName = psdp->device; + if (flags) *flags = 0; + return TRUE; +} + +/* _X_EXPORT */ pointer xf86MapSbusMem(sbusDevicePtr psdp, unsigned long offset, unsigned long size) { pointer ret; - unsigned long pagemask = xf86getpagesize() - 1; - unsigned long off = offset & ~pagemask; - unsigned long len = ((offset + size + pagemask) & ~pagemask) - off; - + unsigned long pagemask, off, len; + unsigned int devOffset[2], fbSize; + if (!psdp || !size) return NULL; if (psdp->fd == -1) { psdp->fd = open(psdp->device, O_RDWR); if (psdp->fd == -1) return NULL; - } else if (psdp->fd < 0) + psdp->mmapCount = 0; + } else if (psdp->fd < 0) { + return NULL; + } + + devOffset[0] = offset; + devOffset[1] = 0; + fbSize = size; + if (!xf86ExploreSbusUpaMemorySpace(psdp, NULL, devOffset, &fbSize, NULL, NULL) || + (devOffset[1] != 0)) return NULL; - ret = (pointer) mmap (NULL, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, + offset = devOffset[0]; + pagemask = xf86getpagesize() - 1; + off = offset & ~pagemask; + len = ((offset + size + pagemask) & ~pagemask) - off; + + ret = (pointer) mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, psdp->fd, off); if (ret == (pointer) -1) { - ret = (pointer) mmap (NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, + ret = (pointer) mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, psdp->fd, off); - } if (ret == (pointer) -1) return NULL; + } + psdp->mmapCount++; return (char *)ret + (offset - off); } -_X_EXPORT void +/* _X_EXPORT */ void xf86UnmapSbusMem(sbusDevicePtr psdp, pointer addr, unsigned long size) { unsigned long mask = xf86getpagesize() - 1; @@ -593,7 +686,7 @@ } /* Tell OS that we are driving the HW cursor ourselves. */ -_X_EXPORT void +/* _X_EXPORT */ void xf86SbusHideOsHwCursor(sbusDevicePtr psdp) { struct fbcursor fbcursor; @@ -614,7 +707,7 @@ } /* Set HW cursor colormap. */ -_X_EXPORT void +/* _X_EXPORT */ void xf86SbusSetOsHwCursorCmap(sbusDevicePtr psdp, int bg, int fg) { struct fbcursor fbcursor; diff -Nurb hw/xfree86/os-support/bus/xf86Sbus.h hw/xfree86/os-support/bus/xf86Sbus.h --- hw/xfree86/os-support/bus/xf86Sbus.h 2007-04-28 05:17:00.941365000 +0200 +++ hw/xfree86/os-support/bus/xf86Sbus.h 2007-04-28 05:20:18.055583600 +0200 @@ -43,11 +43,12 @@ #include #include #include -#else +# else #include -#endif +# endif #else -#include +# include + #endif #ifndef FBTYPE_SUNGP3 @@ -63,7 +64,7 @@ #define FBTYPE_TCXCOLOR -1 #endif #ifndef FBTYPE_CREATOR -#define FBTYPE_CREATOR -1 +#define FBTYPE_CREATOR 8192 /* -1 */ #endif #endif /* _XF86_SBUS_H */