From 34c950c4df410da18c3d6ffb16a9e8de975dae3d Mon Sep 17 00:00:00 2001 From: root Date: Fri, 13 Mar 2009 12:10:47 -0400 Subject: initial commit of first attempt --- lssbus.py | 505 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 505 insertions(+) create mode 100644 lssbus.py diff --git a/lssbus.py b/lssbus.py new file mode 100644 index 0000000..d148e1e --- /dev/null +++ b/lssbus.py @@ -0,0 +1,505 @@ +#!/usr/bin/python -tt + +import os +import fcntl +import struct + +from ctypes import * + +CLASS_UNSPEC, CLASS_OTHER, CLASS_NETWORK, CLASS_SCSI, CLASS_MOUSE, \ +CLASS_AUDIO, CLASS_VIDEO = range(7) + +OPROMMAXPARAM = 4096 # /* Maximum size of oprom_array. */ + +OPROMGETOPT = 0x20004F01 +OPROMSETOPT = 0x20004F02 +OPROMNXTOPT = 0x20004F03 +OPROMSETOPT2 = 0x20004F04 +OPROMNEXT = 0x20004F05 +OPROMCHILD = 0x20004F06 +OPROMGETPROP = 0x20004F07 +OPROMNXTPROP = 0x20004F08 +OPROMU2P = 0x20004F09 +OPROMGETCONS = 0x20004F0A +OPROMGETFBNAME = 0x20004F0B +OPROMGETBOOTARGS = 0x20004F0C + +# Linux extensions +# Arguments in oprom_array: +OPROMSETCUR = 0x20004FF0 # int node - Sets current node +OPROMPCI2NODE = 0x20004FF1 # int pci_bus, pci_devfn - Sets current node to PCI device's node +OPROMPATH2NODE = 0x20004FF2 # char path[] - Set current node from fully qualified PROM path + +MAX_VAL = 4096-128-4 + +#class OpenPromIO(Structure): +# """ struct openpromio +# { +# u_int oprom_size; /* Actual size of the oprom_array. */ +# char oprom_array[1]; /* Holds property names and values. */ +# }; +# """ +# _fields_ = [ +# ('oprom_size', c_uint), +# # FIXME: this is not right... +# #('oprom_array', c_char_p) +# ('oprom_array', POINTER(c_int)) +# ] +# +#openpromio = OpenPromIO() + + +class OpenProm(object): + dev = '/dev/openprom' + + current_node = None + + def __init__(self): + self.promfd = open(self.dev) + + def get_sibling(self, node): + """ + static int prom_getsibling(int node) + { + DECL_OP(sizeof(int)); + + if (node == -1) return 0; + *(int *)op->oprom_array = node; + if (ioctl (promfd, OPROMNEXT, op) < 0) + return 0; + prom_current_node = *(int *)op->oprom_array; + return *(int *)op->oprom_array; + } + """ + if node == -1: + return 0 + + # trying the struct method... + #args = struct.pack('Is', sizeof(c_int), '') + #args = struct.pack('Is', sizeof(c_int), buffer(c_int(node))[:]) + #args = struct.pack('Is', sizeof(c_int), struct.pack('I', 0)) + + # lets try the ctypes Structure method + #openpromio.oprom_size = sizeof(c_int) + #openpromio.oprom_array = pointer(c_int(0)) + #args = buffer(openpromio)[:] + + args = struct.pack('II', 4, node) + #print "ioctl(%r, %r, %r)" % (self.promfd, OPROMNEXT, args) + result = fcntl.ioctl(self.promfd, OPROMNEXT, args) + oprom_size, oprom_array = struct.unpack('II', result) + assert oprom_size == 4 + assert oprom_array + print "oprom_array = ", oprom_array + self.current_node = oprom_array + return oprom_array + + def get_property(self, prop): + """ + static char *prom_getproperty(char *prop, int *lenp) + { + DECL_OP(MAX_VAL); + + strcpy (op->oprom_array, prop); + if (ioctl (promfd, OPROMGETPROP, op) < 0) + return 0; + if (lenp) *lenp = op->oprom_size; + return op->oprom_array; + } + """ + print "get_property(%s)" % prop + args = struct.pack('I%ds' % len(prop), MAX_VAL, prop) + #print "ioctl(%r, %r, %r)" % (self.promfd, OPROMGETPROP, args) + results = fcntl.ioctl(self.promfd, OPROMGETPROP, args) + oprom_size, oprom_array = struct.unpack('I%ds' % len(prop), results) + #print "oprom_size =", oprom_size + print "oprom_array =", oprom_array + return oprom_size, oprom_array + + def get_child(self, node): + print "get_child(%s)" % node + if node in (None, -1): + return None + args = struct.pack('II', sizeof(c_int), node) + print "ioctl(%r, %r, %r)" % (self.promfd, OPROMCHILD, args) + results = fcntl.ioctl(self.promfd, OPROMCHILD, args) + oprom_size, oprom_array = struct.unpack('II', results) + print "oprom_size =", oprom_size + print "oprom_array =", oprom_array + self.current_node = oprom_array + return oprom_array + + + def walk(self, node, sbus, ebus, probe_class, devlist): + nsbus = sbus + nebus = ebus + type = None + port = None + module = None + dev_class = CLASS_UNSPEC; + depth = -1 + width = 1152 + height = 900 + freq = 0 + sense = -1 + + size, prop = self.get_property('device_type') + if size <= 0: + prop = None + + while probe_class in (CLASS_NETWORK, CLASS_UNSPEC): + if not prop or prop != 'network': + break + size, prop = self.get_property('name') + if not prop or size <= 0: + size, prop = self.get_property('device_type') + break + + # umm, do we need to do this?? + # while ((*prop >= 'A' && *prop <= 'Z') || *prop == ',') prop++; + if not sbus: + print "no sbus" + size, prop = self.get_property('device_type') + break + if prop == 'hme': + type = "Sun Happy Meal Ethernet" + module = "sunhme" + dev_class = CLASS_NETWORK + elif prop == 'le': + type = "Sun Lance Ethernet" + module = "sunlance" + dev_class = CLASS_NETWORK + elif prop == 'qe': + size, prop = self.get_property('channel#') + if prop and size == 4 and prop[0]: + print "TODO: goto next" + type = "Sun Quad Ethernet" + module = "sunqe" + dev_class = CLASS_NETWORK + elif prop in ('mlanai', 'myri'): + type = "MyriCOM MyriNET Gigabit Ethernet" + module = "myri_sbus" + dev_class = CLASS_NETWORK + + size, prop = self.get_property('device_type') + break + + while probe_class in (CLASS_SCSI, CLASS_UNSPEC): + is_scsi = prop == 'scsi' + size, prop = self.get_property('name') + if not prop or size <= 0: + print "no prop or size..." + size, prop = self.get_property('device_type') + break + #while ((*prop >= 'A' && *prop <= 'Z') || *prop == ',') prop++; + if not sbus: + print "no sbus.. breaking" + size, prop = self.get_property('device_type') + break + if not is_scsi and prop == 'soc' and prop == 'socal': + print "soc/socal" + size, prop = self.get_property('device_type') + break + print "Probing SCSI devices" + if prop == 'soc': + type = "Sun SPARCStorage Array" + module = "fc4:soc:pluto" + dev_class = CLASS_SCSI + elif prop == 'socal': + type = "Sun Enterprise Network Array" + module = "fc4:socal:fcal" + dev_class = CLASS_SCSI + elif prop == 'esp': + type = "Sun Enhanced SCSI Processor (ESP)" + module = "esp" + dev_class = CLASS_SCSI + elif prop == 'fas': + type = "Sun Swift (ESP)" + module = "esp" + dev_class = CLASS_SCSI + elif prop == 'ptisp': + type = "Performance Technologies ISP" + module = "qlogicpti" + dev_class = CLASS_SCSI + elif prop == 'isp': + type = "QLogic ISP" + module = "qlogicpti" + dev_class = CLASS_SCSI + + size, prop = self.get_property('device_type') + + while probe_class in (CLASS_AUDIO, CLASS_UNSPEC): + size, prop = self.get_property('name') + if not prop or size <= 0: + print "no prop" + size, prop = self.get_property('device_type') + break + if ',' in prop: + print "Splitting up by comma" + prop = prop.split(',')[1] + print "prop =", prop + if prop == 'audio': + type = "AMD7930" + module = "amd7930" + dev_class = CLASS_AUDIO + elif prop == 'CS4231': + if ebus: + type = "CS4231 EB2 DMA (PCI)" + else: + type = "CS4231 APC DMA (SBUS)" + module = "cs4231" + dev_class = CLASS_AUDIO + elif prop == 'DBRIe': + type = "SS10/SS20 DBRI" + module = "dbri" + dev_class = CLASS_AUDIO + + size, prop = self.get_property('device_type') + break + + while probe_class in (CLASS_VIDEO, CLASS_UNSPEC): + if not prop or prop != 'display': + print "prop not a display" + break + size, prop = self.get_property('name') + if not prop or size <= 0: + print "no prop" + size, prop = self.get_property('device_type') + break + print "Probing video devices..." + #while ((*prop >= 'A' && *prop <= 'Z') || *prop == ',') prop++; + if not sbus and prop not in ('ffb', 'afb', 'cgfourteen'): + print "not ffb, afb, cgfourteen, etc..." + size, prop = self.get_property('device_type') + break + if prop == "bwtwo": + type = "Sun Monochrome (bwtwo)" + depth = 1 + elif prop == "cgthree": + type = "Sun Color3 (cgthree)" + depth = 8 + elif prop == "cgeight": + type = "Sun CG8/RasterOps" + depth = 8 + elif prop == "cgtwelve": + type = "Sun GS (cgtwelve)" + depth = 24 + elif prop == "gt": + type = "Sun Graphics Tower" + depth = 24 + elif prop == "mgx": + size, prop = self.get_property("fb_size"); + if prop and size == 4 and prop == 0x400000: + type = "Quantum 3D MGXplus with 4M VRAM" + else: + type = "Quantum 3D MGXplus" + depth = 24 + elif prop == "cgsix": + chiprev = 0 + vmsize = 0 + size, prop = self.get_property("chiprev") + if prop and size == 4: + chiprev = prop + size, prop = self.get_property("montype") + if prop and size == 4: + sense = prop + size, prop = self.get_property("vfreq") + if prop and size == 4: + freq = prop + size, prop = self.get_property("vmsize") + if prop and size == 4: + vmsize = prop + + if chiprev == 0: + type = "Sun Unknown GX" + elif chiprev in range(1, 5): + type = "Sun Double width GX" + elif chiprev in range(5, 10): + type = "Sun Single width GX" + elif chiprev == 11: + if vmsize == 2: + type = "Sun Turbo GX with 1M VSIMM" + elif vmsize == 4: + type = "Sun Turbo GX Plus" + else: + type = "Sun Turbo GX" + depth = 8 + + elif prop == "cgfourteen": + size = 0 + s, prop = self.get_property("vfreq") + if prop and s == 4: + freq = prop + s, prop = self.get_property("reg") + if prop and not (s % 12) and s > 0: + size = prop + s - 4 + if size == 0x400000: + type = "Sun SX with 4M VSIMM" + elif size == 0x800000: + type = "Sun SX with 8M VSIMM" + else: + type = "Sun SX" + depth = 24 + elif prop == "leo": + size, prop = self.get_property("model"); + if prop and size > 0 and '501-2503' not in prop: + type = "Sun Turbo ZX" + else: + type = "Sun ZX or Turbo ZX" + depth = 24 + elif prop == "tcx": + print "TODO" + #if (prom_getbool("tcx-8-bit")) { + # type = "Sun TCX (8bit)"; + # depth = 8; + #} else { + # type = "Sun TCX (S24)"; + # depth = 24; + #} + elif prop == "afb": + btype = 0; + size, prop = self.get_property("vfreq") + if prop and size == 4: + freq = prop + size, prop = self.get_property("board_type"); + if prop and size == 4: + btype = prop + if btype == 3: + type = "Sun Elite3D-M6 Horizontal" + else: + type = "Sun Elite3D" + depth = 24 + elif prop == "ffb": + btype = 0 + size, prop = self.get_property("vfreq"); + if prop and size == 4: + freq = prop + size, prop = self.get_property("board_type") + if prop and size == 4: + btype = prop + if btype == 0x08: + type="Sun FFB 67MHz Creator" + elif btype == 0x0b: + type="Sun FFB 67MHz Creator 3D" + elif btype == 0x1b: + type="Sun FFB 75MHz Creator 3D" + elif btype in (0x20, 0x28): + type="Sun FFB2 Vertical Creator" + elif btype in (0x23, 0x2b): + type="Sun FFB2 Vertical Creator 3D" + elif btype == 0x30: + type="Sun FFB2+ Vertical Creator" + elif btype == 0x33: + type="Sun FFB2+ Vertical Creator 3D" + elif btype in (0x40, 0x48): + type="Sun FFB2 Horizontal Creator" + elif btype in (0x43, 0x4b): + type="Sun FFB2 Horizontal Creator 3D" + else: + type = "Sun FFB" + depth = 24 + if type: + size, prop = self.get_property("width") + if prop and size == 4: + width = prop + size, prop = self.get_property("height") + if (prop and size == 4): + height = prop + + size, prop = self.get_property("device_type") + break + + if type: + print "TODO: create new dev!" + """ + struct sbusDevice *newDev; + newDev=sbusNewDevice(NULL); + if (depth != -1) { /* it's a video device */ + newDev->width = width; + newDev->height = height; + newDev->freq = freq; + newDev->monitor = sense; + } + newDev->desc = strdup(type); + switch (depth) { + case 1: + newDev->class = CLASS_VIDEO; + break; + case 8: + newDev->class = CLASS_VIDEO; + break; + case 24: + newDev->class = CLASS_VIDEO; + break; + default: + newDev->class = devClass; + } + if (newDev->class == CLASS_NETWORK) + newDev->device = strdup("eth"); + if (port) newDev->device = strdup(port); + if (devlist) newDev->next = devlist; + devlist = (struct device *)newDev; + } + """ + + size, prop = self.get_property('name') + if prop and size > 0: + if prop in ('sbus', 'sbi'): + nsbus = 1 + if prop == 'ebus': + nebus = 1 + + nextnode = self.get_child(node) + print "nextnode =", nextnode + if nextnode: + print "Walking children..." + devlist = self.walk(nextnode, nsbus, nebus, probe_class, devlist) + print "Done walking child" + print "Getting sibling" + nextnode = self.get_sibling(node) + if nextnode: + print "Walking sibling" + devlist = self.walk(nextnode, sbus, ebus, probe_class, devlist) + print "Done walking sibling" + + return devlist + +class SBusDevice(object): + + def __init__(self, dev_class, device, desc, next): + self.dev_class = dev_class + self.device = device + self.desc = desc + self.next = next + + +class LsBus(object): + + def sbus_probe(self, probe_class, devlist): + """ + given a class to probe, returns a list of devices found which match + """ + if probe_class in (CLASS_MOUSE, CLASS_UNSPEC): + if os.path.exists('/dev/sunmouse'): + print "Found /dev/sunmouse" + mousedev = SBusDevice(dev_class=CLASS_MOUSE, + device='sunmouse', + desc='Sun Mouse', + next=devlist) + devlist = mousedev + if probe_class in (CLASS_UNSPEC, CLASS_OTHER, CLASS_NETWORK, CLASS_SCSI, + CLASS_VIDEO, CLASS_AUDIO): + prom = OpenProm() + prom_root_node = prom.get_sibling(0) + if not prom_root_node: + print "No prom_root_node found!" + return devlist + + devlist = prom.walk(prom_root_node, 0, 0, probe_class, devlist) + return devlist + + +if __name__ == '__main__': + devices = [] + lsbus = LsBus() + print lsbus.sbus_probe(CLASS_UNSPEC, devices) -- cgit