summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorroot <root@ultra10.(none)>2009-03-13 12:10:47 -0400
committerroot <root@ultra10.(none)>2009-03-13 12:10:47 -0400
commit34c950c4df410da18c3d6ffb16a9e8de975dae3d (patch)
tree30d0352068cf13c89e86b4ff0298006556da62d1
downloadpython-sbus-34c950c4df410da18c3d6ffb16a9e8de975dae3d.tar.gz
python-sbus-34c950c4df410da18c3d6ffb16a9e8de975dae3d.tar.xz
python-sbus-34c950c4df410da18c3d6ffb16a9e8de975dae3d.zip
initial commit of first attempt
-rw-r--r--lssbus.py505
1 files changed, 505 insertions, 0 deletions
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)