void xf86SbusConfigureNewDev(void *busData, sbusDevicePtr sBus, GDevRec * GDev) { char *promPath = NULL; sBus = (sbusDevicePtr) busData; GDev->identifier = sBus->descr; if (sparcPromInit() >= 0) { promPath = sparcPromNode2Pathname(&sBus->node); sparcPromClose(); } if (promPath) { XNFasprintf(&GDev->busID, "SBUS:%s", promPath); free(promPath); } else { XNFasprintf(&GDev->busID, "SBUS:fb%d", sBus->fbNum); } }
static void bus_sbus_newdev_configure(void *busData, int i) { #if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__) char *promPath = NULL; DevToConfig[i].sVideo = (sbusDevicePtr) busData; DevToConfig[i].GDev.identifier = DevToConfig[i].sVideo->descr; if (sparcPromInit() >= 0) { promPath = sparcPromNode2Pathname(&DevToConfig[i].sVideo->node); sparcPromClose(); } if (promPath) { DevToConfig[i].GDev.busID = xnfalloc(strlen(promPath) + 6); sprintf(DevToConfig[i].GDev.busID, "SBUS:%s", promPath); xfree(promPath); } else { DevToConfig[i].GDev.busID = xnfalloc(12); sprintf(DevToConfig[i].GDev.busID, "SBUS:fb%d", DevToConfig[i].sVideo->fbNum); } #endif }
void xf86SbusProbe(void) { int i, useProm = 0; char fbDevName[32]; sbusDevicePtr psdp, *psdpp; xf86SbusInfo = malloc(sizeof(psdp)); *xf86SbusInfo = NULL; 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. */ if (useProm && psdp->node.node) { char *prop, *promPath; int len, chiprev, vmsize; 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; prop = sparcPromGetProperty(&psdp->node, "vmsize", &len); if (prop && len == 4) vmsize = *(int *)prop; switch (chiprev) { case 1: case 2: case 3: case 4: psdp->descr = "Sun Double width GX"; break; case 5: case 6: case 7: case 8: case 9: psdp->descr = "Sun Single width GX"; break; case 11: switch (vmsize) { case 2: psdp->descr = "Sun Turbo GX with 1M VSIMM"; break; case 4: psdp->descr = "Sun Turbo GX Plus"; break; default: psdp->descr = "Sun Turbo GX"; break; } } break; case SBUS_DEVICE_CG14: prop = sparcPromGetProperty(&psdp->node, "reg", &len); vmsize = 0; if (prop && !(len % 12) && len > 0) vmsize = *(int *)(prop + len - 4); switch (vmsize) { case 0x400000: psdp->descr = "Sun SX with 4M VSIMM"; break; case 0x800000: psdp->descr = "Sun SX with 8M VSIMM"; break; } break; case SBUS_DEVICE_LEO: prop = sparcPromGetProperty(&psdp->node, "model", &len); if (prop && len > 0 && !strstr(prop, "501-2503")) psdp->descr = "Sun Turbo ZX"; break; case SBUS_DEVICE_TCX: if (sparcPromGetBool(&psdp->node, "tcx-8-bit")) psdp->descr = "Sun TCX (8bit)"; else 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")) { if (chiprev == 3) psdp->descr = "Sun|Elite3D-M6 Horizontal"; } else { switch (chiprev) { case 0x08: psdp->descr = "Sun FFB 67MHz Creator"; break; case 0x0b: psdp->descr = "Sun FFB 67MHz Creator 3D"; break; case 0x1b: psdp->descr = "Sun FFB 75MHz Creator 3D"; break; case 0x20: case 0x28: psdp->descr = "Sun FFB2 Vertical Creator"; break; case 0x23: case 0x2b: psdp->descr = "Sun FFB2 Vertical Creator 3D"; break; case 0x30: psdp->descr = "Sun FFB2+ Vertical Creator"; break; case 0x33: psdp->descr = "Sun FFB2+ Vertical Creator 3D"; break; case 0x40: case 0x48: psdp->descr = "Sun FFB2 Horizontal Creator"; break; case 0x43: case 0x4b: psdp->descr = "Sun FFB2 Horizontal Creator 3D"; break; } } break; } xf86Msg(X_PROBED, "SBUS:(0x%08x) %s", psdp->node.node, psdp->descr); promPath = sparcPromNode2Pathname (&psdp->node); if (promPath) { xf86ErrorF(" at %s", promPath); free(promPath); } } else xf86Msg(X_PROBED, "SBUS: %s", psdp->descr); xf86ErrorF("\n"); } if (useProm) sparcPromClose(); }
int xf86MatchSbusInstances(const char *driverName, int sbusDevId, GDevPtr *devList, int numDevs, DriverPtr drvp, int **foundEntities) { int i,j; sbusDevicePtr psdp, *psdpp; int numClaimedInstances = 0; int allocatedInstances = 0; int numFound = 0; GDevPtr devBus = NULL; GDevPtr dev = NULL; int *retEntities = NULL; int useProm = 0; struct Inst { sbusDevicePtr sbus; GDevPtr dev; Bool claimed; /* BusID matches with a device section */ } *instances = NULL; *foundEntities = NULL; for (psdpp = xf86SbusInfo, psdp = *psdpp; psdp; psdp = *++psdpp) { if (psdp->devId != sbusDevId) continue; if (psdp->fd == -2) continue; ++allocatedInstances; instances = xnfrealloc(instances, allocatedInstances * sizeof(struct Inst)); instances[allocatedInstances - 1].sbus = psdp; instances[allocatedInstances - 1].dev = NULL; instances[allocatedInstances - 1].claimed = FALSE; numFound++; } /* * This may be debatable, but if no SBUS devices with a matching vendor * type is found, return zero now. It is probably not desirable to * allow the config file to override this. */ if (allocatedInstances <= 0) { free(instances); return 0; } if (sparcPromInit() >= 0) useProm = 1; if (xf86DoConfigure && xf86DoConfigurePass1) { GDevPtr pGDev; int actualcards = 0; for (i = 0; i < allocatedInstances; i++) { actualcards++; pGDev = xf86AddBusDeviceToConfigure(drvp->driverName, BUS_SBUS, instances[i].sbus, -1); if (pGDev) { /* * XF86Match???Instances() treat chipID and chipRev as * overrides, so clobber them here. */ pGDev->chipID = pGDev->chipRev = -1; } } free(instances); if (useProm) sparcPromClose(); return actualcards; } DebugF("%s instances found: %d\n", driverName, allocatedInstances); for (i = 0; i < allocatedInstances; i++) { char *promPath = NULL; psdp = instances[i].sbus; devBus = NULL; dev = NULL; if (useProm && psdp->node.node) promPath = sparcPromNode2Pathname(&psdp->node); for (j = 0; j < numDevs; j++) { if (devList[j]->busID && *devList[j]->busID) { if (xf86CompareSbusBusString(devList[j]->busID, psdp->fbNum)) { if (devBus) xf86MsgVerb(X_WARNING,0, "%s: More than one matching Device section for " "instance (BusID: %s) found: %s\n", driverName,devList[j]->identifier, devList[j]->busID); else devBus = devList[j]; } } else { if (!dev && !devBus) { if (promPath) xf86Msg(X_PROBED, "Assigning device section with no busID to SBUS:%s\n", promPath); else xf86Msg(X_PROBED, "Assigning device section with no busID to SBUS:fb%d\n", psdp->fbNum); dev = devList[j]; } else xf86MsgVerb(X_WARNING, 0, "%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", driverName, promPath); } else xf86MsgVerb(X_WARNING, 0, "%s: No matching Device section " "for instance (BusID SBUS:fb%d) found\n", driverName, psdp->fbNum); } else if (dev) { numClaimedInstances++; instances[i].claimed = TRUE; instances[i].dev = dev; } free(promPath); } DebugF("%s instances found: %d\n", driverName, numClaimedInstances); /* * Of the claimed instances, check that another driver hasn't already * claimed its slot. */ numFound = 0; for (i = 0; i < allocatedInstances && numClaimedInstances > 0; i++) { if (!instances[i].claimed) continue; psdp = instances[i].sbus; if (!xf86CheckSbusSlot(psdp->fbNum)) continue; DebugF("%s: card at fb%d %08x is claimed by a Device section\n", driverName, psdp->fbNum, psdp->node.node); /* Allocate an entry in the lists to be returned */ numFound++; retEntities = xnfrealloc(retEntities, numFound * sizeof(int)); retEntities[numFound - 1] = xf86ClaimSbusSlot(psdp, drvp, instances[i].dev,instances[i].dev->active ? TRUE : FALSE); } free(instances); if (numFound > 0) { *foundEntities = retEntities; } if (useProm) sparcPromClose(); return numFound; }
Bool xf86ParseSbusBusString(const char *busID, int *fbNum) { /* * The format is assumed to be one of: * "fbN", e.g. "fb1", which means the device corresponding to /dev/fbN * "nameN", e.g. "cgsix0", which means Nth instance of card NAME * "/prompath", e.g. "/sbus@0,10001000/cgsix@3,0" which is PROM pathname * to the device. */ const char *id; int i, len; if (StringToBusType(busID, &id) != BUS_SBUS) return FALSE; if (*id != '/') { if (!strncmp (id, "fb", 2)) { if (!isdigit(id[2])) return FALSE; *fbNum = atoi(id + 2); return TRUE; } else { sbusDevicePtr *psdpp; int devId; for (i = 0, len = 0; sbusDeviceTable[i].devId; i++) { len = strlen(sbusDeviceTable[i].promName); if (!strncmp (sbusDeviceTable[i].promName, id, len) && isdigit(id[len])) break; } devId = sbusDeviceTable[i].devId; if (!devId) return FALSE; i = atoi(id + len); for (psdpp = xf86SbusInfo; *psdpp; ++psdpp) { if ((*psdpp)->devId != devId) continue; if (!i) { *fbNum = (*psdpp)->fbNum; return TRUE; } i--; } } return FALSE; } if (sparcPromInit() >= 0) { i = sparcPromPathname2Node(id); sparcPromClose(); if (i) { sbusDevicePtr *psdpp; for (psdpp = xf86SbusInfo; *psdpp; ++psdpp) { if ((*psdpp)->node.node == i) { *fbNum = (*psdpp)->fbNum; return TRUE; } } } } return FALSE; }
/* * This is called by the driver, either through xf86Match???Instances() or * directly. We allocate a GDevRec and fill it in as much as we can, letting * the caller fill in the rest and/or change it as it sees fit. */ GDevPtr xf86AddBusDeviceToConfigure(const char *driver, BusType bus, void *busData, int chipset) { int i, j; pciVideoPtr pVideo = NULL; Bool isPrimary = FALSE; if (xf86DoProbe || !xf86DoConfigure || !xf86DoConfigurePass1) return NULL; /* Check for duplicates */ switch (bus) { case BUS_PCI: pVideo = (pciVideoPtr) busData; for (i = 0; i < nDevToConfig; i++) if (DevToConfig[i].pVideo && (DevToConfig[i].pVideo->bus == pVideo->bus) && (DevToConfig[i].pVideo->device == pVideo->device) && (DevToConfig[i].pVideo->func == pVideo->func)) return NULL; isPrimary = xf86IsPrimaryPci(pVideo); break; case BUS_ISA: /* * This needs to be revisited as it doesn't allow for non-PCI * multihead. */ if (!xf86IsPrimaryIsa()) return NULL; isPrimary = TRUE; for (i = 0; i < nDevToConfig; i++) if (!DevToConfig[i].pVideo) return NULL; break; #if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__) case BUS_SBUS: for (i = 0; i < nDevToConfig; i++) if (DevToConfig[i].sVideo && DevToConfig[i].sVideo->fbNum == ((sbusDevicePtr) busData)->fbNum) return NULL; break; #endif default: return NULL; } /* Allocate new structure occurrence */ i = nDevToConfig++; DevToConfig = xnfrealloc(DevToConfig, nDevToConfig * sizeof(DevToConfigRec)); #if 1 /* Doesn't work when a driver detects more than one adapter */ if ((i > 0) && isPrimary) { memmove(DevToConfig + 1,DevToConfig, (nDevToConfig - 1) * sizeof(DevToConfigRec)); i = 0; } #endif memset(DevToConfig + i, 0, sizeof(DevToConfigRec)); # define NewDevice DevToConfig[i] NewDevice.GDev.chipID = NewDevice.GDev.chipRev = NewDevice.GDev.irq = -1; NewDevice.iDriver = CurrentDriver; /* Fill in what we know, converting the driver name to lower case */ NewDevice.GDev.driver = xnfalloc(strlen(driver) + 1); for (j = 0; (NewDevice.GDev.driver[j] = tolower(driver[j])); j++); switch (bus) { case BUS_PCI: { const char *VendorName; const char *CardName; char busnum[8]; NewDevice.pVideo = pVideo; xf86FindPciNamesByDevice(pVideo->vendor, pVideo->chipType, NOVENDOR, NOSUBSYS, &VendorName, &CardName, NULL, NULL); if (!VendorName) { VendorName = xnfalloc(15); sprintf((char*)VendorName, "Unknown Vendor"); } if (!CardName) { CardName = xnfalloc(14); sprintf((char*)CardName, "Unknown Board"); } NewDevice.GDev.identifier = xnfalloc(strlen(VendorName) + strlen(CardName) + 2); sprintf(NewDevice.GDev.identifier, "%s %s", VendorName, CardName); NewDevice.GDev.vendor = (char *)VendorName; NewDevice.GDev.board = (char *)CardName; NewDevice.GDev.busID = xnfalloc(16); xf86FormatPciBusNumber(pVideo->bus, busnum); sprintf(NewDevice.GDev.busID, "PCI:%s:%d:%d", busnum, pVideo->device, pVideo->func); NewDevice.GDev.chipID = pVideo->chipType; NewDevice.GDev.chipRev = pVideo->chipRev; if (chipset < 0) chipset = (pVideo->vendor << 16) | pVideo->chipType; } break; case BUS_ISA: NewDevice.GDev.identifier = "ISA Adapter"; NewDevice.GDev.busID = "ISA"; break; #if (defined(__sparc__) || defined(__sparc)) && !defined(__OpenBSD__) case BUS_SBUS: { char *promPath = NULL; NewDevice.sVideo = (sbusDevicePtr) busData; NewDevice.GDev.identifier = NewDevice.sVideo->descr; if (sparcPromInit() >= 0) { promPath = sparcPromNode2Pathname(&NewDevice.sVideo->node); sparcPromClose(); } if (promPath) { NewDevice.GDev.busID = xnfalloc(strlen(promPath) + 6); sprintf(NewDevice.GDev.busID, "SBUS:%s", promPath); xfree(promPath); } else { NewDevice.GDev.busID = xnfalloc(12); sprintf(NewDevice.GDev.busID, "SBUS:fb%d", NewDevice.sVideo->fbNum); } } break; #endif default: break; } /* Get driver's available options */ if (xf86DriverList[CurrentDriver]->AvailableOptions) NewDevice.GDev.options = (OptionInfoPtr) (*xf86DriverList[CurrentDriver]->AvailableOptions)(chipset, bus); return &NewDevice.GDev; # undef NewDevice }