#!/usr/bin/python -u # # generate python wrappers from the XML API description # functions = {} enums = {} # { enumType: { enumConstant: enumValue } } import os import sys import string import re if __name__ == "__main__": # launched as a script srcPref = os.path.dirname(sys.argv[0]) else: # imported srcPref = os.path.dirname(__file__) ####################################################################### # # That part if purely the API acquisition phase from the # libvirt API description # ####################################################################### import os import xmllib try: import sgmlop except ImportError: sgmlop = None # accelerator not available debug = 0 if sgmlop: class FastParser: """sgmlop based XML parser. this is typically 15x faster than SlowParser...""" def __init__(self, target): # setup callbacks self.finish_starttag = target.start self.finish_endtag = target.end self.handle_data = target.data # activate parser self.parser = sgmlop.XMLParser() self.parser.register(self) self.feed = self.parser.feed self.entity = { "amp": "&", "gt": ">", "lt": "<", "apos": "'", "quot": '"' } def close(self): try: self.parser.close() finally: self.parser = self.feed = None # nuke circular reference def handle_entityref(self, entity): # entity try: self.handle_data(self.entity[entity]) except KeyError: self.handle_data("&%s;" % entity) else: FastParser = None class SlowParser(xmllib.XMLParser): """slow but safe standard parser, based on the XML parser in Python's standard library.""" def __init__(self, target): self.unknown_starttag = target.start self.handle_data = target.data self.unknown_endtag = target.end xmllib.XMLParser.__init__(self) def getparser(target = None): # get the fastest available parser, and attach it to an # unmarshalling object. return both objects. if target is None: target = docParser() if FastParser: return FastParser(target), target return SlowParser(target), target class docParser: def __init__(self): self._methodname = None self._data = [] self.in_function = 0 def close(self): if debug: print "close" def getmethodname(self): return self._methodname def data(self, text): if debug: print "data %s" % text self._data.append(text) def start(self, tag, attrs): if debug: print "start %s, %s" % (tag, attrs) if tag == 'function': self._data = [] self.in_function = 1 self.function = None self.function_cond = None self.function_args = [] self.function_descr = None self.function_return = None self.function_file = None if attrs.has_key('name'): self.function = attrs['name'] if attrs.has_key('file'): self.function_file = attrs['file'] elif tag == 'cond': self._data = [] elif tag == 'info': self._data = [] elif tag == 'arg': if self.in_function == 1: self.function_arg_name = None self.function_arg_type = None self.function_arg_info = None if attrs.has_key('name'): self.function_arg_name = attrs['name'] if self.function_arg_name == 'from': self.function_arg_name = 'frm' if attrs.has_key('type'): self.function_arg_type = attrs['type'] if attrs.has_key('info'): self.function_arg_info = attrs['info'] elif tag == 'return': if self.in_function == 1: self.function_return_type = None self.function_return_info = None self.function_return_field = None if attrs.has_key('type'): self.function_return_type = attrs['type'] if attrs.has_key('info'): self.function_return_info = attrs['info'] if attrs.has_key('field'): self.function_return_field = attrs['field'] elif tag == 'enum': enum(attrs['type'],attrs['name'],attrs['value']) def end(self, tag): if debug: print "end %s" % tag if tag == 'function': if self.function != None: function(self.function, self.function_descr, self.function_return, self.function_args, self.function_file, self.function_cond) self.in_function = 0 elif tag == 'arg': if self.in_function == 1: self.function_args.append([self.function_arg_name, self.function_arg_type, self.function_arg_info]) elif tag == 'return': if self.in_function == 1: self.function_return = [self.function_return_type, self.function_return_info, self.function_return_field] elif tag == 'info': str = '' for c in self._data: str = str + c if self.in_function == 1: self.function_descr = str elif tag == 'cond': str = '' for c in self._data: str = str + c if self.in_function == 1: self.function_cond = str def function(name, desc, ret, args, file, cond): functions[name] = (desc, ret, args, file, cond) def enum(type, name, value): if not enums.has_key(type): enums[type] = {} enums[type][name] = value ####################################################################### # # Some filtering rukes to drop functions/types which should not # be exposed as-is on the Python interface # ####################################################################### functions_failed = [] functions_skipped = [ "virConnectListDomains" ] skipped_modules = { } skipped_types = { # 'int *': "usually a return type", } ####################################################################### # # Table of remapping to/from the python type or class to the C # counterpart. # ####################################################################### py_types = { 'void': (None, None, None, None), 'int': ('i', None, "int", "int"), 'long': ('l', None, "long", "long"), 'double': ('d', None, "double", "double"), 'unsigned int': ('i', None, "int", "int"), 'unsigned long': ('l', None, "long", "long"), 'unsigned long long': ('l', None, "longlong", "long long"), 'unsigned char *': ('z', None, "charPtr", "char *"), 'char *': ('z', None, "charPtr", "char *"), 'const char *': ('z', None, "charPtrConst", "const char *"), 'virDomainPtr': ('O', "virDomain", "virDomainPtr", "virDomainPtr"), 'const virDomainPtr': ('O', "virDomain", "virDomainPtr", "virDomainPtr"), 'virDomain *': ('O', "virDomain", "virDomainPtr", "virDomainPtr"), 'const virDomain *': ('O', "virDomain", "virDomainPtr", "virDomainPtr"), 'virNetworkPtr': ('O', "virNetwork", "virNetworkPtr", "virNetworkPtr"), 'const virNetworkPtr': ('O', "virNetwork", "virNetworkPtr", "virNetworkPtr"), 'virNetwork *': ('O', "virNetwork", "virNetworkPtr", "virNetworkPtr"), 'const virNetwork *': ('O', "virNetwork", "virNetworkPtr", "virNetworkPtr"), 'virStoragePoolPtr': ('O', "virStoragePool", "virStoragePoolPtr", "virStoragePoolPtr"), 'const virStoragePoolPtr': ('O', "virStoragePool", "virStoragePoolPtr", "virStoragePoolPtr"), 'virStoragePool *': ('O', "virStoragePool", "virStoragePoolPtr", "virStoragePoolPtr"), 'const virStoragePool *': ('O', "virStoragePool", "virStoragePoolPtr", "virStoragePoolPtr"), 'virStorageVolPtr': ('O', "virStorageVol", "virStorageVolPtr", "virStorageVolPtr"), 'const virStorageVolPtr': ('O', "virStorageVol", "virStorageVolPtr", "virStorageVolPtr"), 'virStorageVol *': ('O', "virStorageVol", "virStorageVolPtr", "virStorageVolPtr"), 'const virStorageVol *': ('O', "virStorageVol", "virStorageVolPtr", "virStorageVolPtr"), 'virConnectPtr': ('O', "virConnect", "virConnectPtr", "virConnectPtr"), 'const virConnectPtr': ('O', "virConnect", "virConnectPtr", "virConnectPtr"), 'virConnect *': ('O', "virConnect", "virConnectPtr", "virConnectPtr"), 'const virConnect *': ('O', "virConnect", "virConnectPtr", "virConnectPtr"), } py_return_types = { } unknown_types = {} foreign_encoding_args = ( ) ####################################################################### # # This part writes the C <-> Python stubs libvirt2-py.[ch] and # the table libxml2-export.c to add when registrering the Python module # ####################################################################### # Class methods which are written by hand in libvir.c but the Python-level # code is still automatically generated (so they are not in skip_function()). skip_impl = ( 'virConnectListDomainsID', 'virConnectListDefinedDomains', 'virConnectListNetworks', 'virConnectListDefinedNetworks', 'virConnectListStoragePools', 'virConnectListDefinedStoragePools', 'virConnectListStorageVols', 'virConnectListDefinedStorageVols', 'virConnGetLastError', 'virGetLastError', 'virDomainGetInfo', 'virNodeGetInfo', 'virDomainGetUUID', 'virDomainLookupByUUID', 'virNetworkGetUUID', 'virNetworkLookupByUUID', 'virDomainGetAutostart', 'virNetworkGetAutostart', 'virDomainBlockStats', 'virDomainInterfaceStats', 'virNodeGetCellsFreeMemory', 'virDomainGetSchedulerType', 'virDomainGetSchedulerParameters', 'virDomainSetSchedulerParameters', 'virDomainGetVcpus', 'virDomainPinVcpu', 'virStoragePoolGetUUID', 'virStoragePoolLookupByUUID', 'virStorageVolGetUUID', 'virStorageVolLookupByUUID', 'virStoragePoolGetInfo', 'virStorageVolGetInfo', 'virStoragePoolGetAutostart', 'virStoragePoolListVolumes', ) # These are functions which the generator skips completly - no python # or C code is generated. Generally should not be used for any more # functions than those already listed skip_function = ( 'virConnectListDomains', # Python API is called virConectListDomainsID for unknown reasons 'virConnSetErrorFunc', # Not used in Python API XXX is this a bug ? 'virResetError', # Not used in Python API XXX is this a bug ? 'virConnectGetVersion', # Not used in Python API XXX is this a bug ? 'virGetVersion', # Python C code is manually written 'virSetErrorFunc', # Python API is called virRegisterErrorHandler for unknown reasons 'virConnCopyLastError', # Python API is called virConnGetLastError instead 'virCopyLastError', # Python API is called virGetLastError instead 'virConnectOpenAuth', # Python C code is manually written 'virDefaultErrorFunc', # Python virErrorFuncHandler impl calls this from C ) def print_function_wrapper(name, output, export, include): global py_types global unknown_types global functions global skipped_modules try: (desc, ret, args, file, cond) = functions[name] except: print "failed to get function %s infos" return if skipped_modules.has_key(file): return 0 if name in skip_function: return 0 if name in skip_impl: # Don't delete the function entry in the caller. return 1 c_call = ""; format="" format_args="" c_args="" c_return="" c_convert="" num_bufs=0 for arg in args: # This should be correct if arg[1][0:6] == "const ": arg[1] = arg[1][6:] c_args = c_args + " %s %s;\n" % (arg[1], arg[0]) if py_types.has_key(arg[1]): (f, t, n, c) = py_types[arg[1]] if (f == 'z') and (name in foreign_encoding_args) and (num_bufs == 0): f = 't#' if f != None: format = format + f if t != None: format_args = format_args + ", &pyobj_%s" % (arg[0]) c_args = c_args + " PyObject *pyobj_%s;\n" % (arg[0]) c_convert = c_convert + \ " %s = (%s) Py%s_Get(pyobj_%s);\n" % (arg[0], arg[1], t, arg[0]); else: format_args = format_args + ", &%s" % (arg[0]) if f == 't#': format_args = format_args + ", &py_buffsize%d" % num_bufs c_args = c_args + " int py_buffsize%d;\n" % num_bufs num_bufs = num_bufs + 1 if c_call != "": c_call = c_call + ", "; c_call = c_call + "%s" % (arg[0]) else: if skipped_types.has_key(arg[1]): return 0 if unknown_types.has_key(arg[1]): lst = unknown_types[arg[1]] lst.append(name) else: unknown_types[arg[1]] = [name] return -1 if format != "": format = format + ":%s" % (name) if ret[0] == 'void': if file == "python_accessor": if args[1][1] == "char *": c_call = "\n free(%s->%s);\n" % ( args[0][0], args[1][0], args[0][0], args[1][0]) c_call = c_call + " %s->%s = (%s)strdup((const xmlChar *)%s);\n" % (args[0][0], args[1][0], args[1][1], args[1][0]) else: c_call = "\n %s->%s = %s;\n" % (args[0][0], args[1][0], args[1][0]) else: c_call = "\n %s(%s);\n" % (name, c_call); ret_convert = " Py_INCREF(Py_None);\n return(Py_None);\n" elif py_types.has_key(ret[0]): (f, t, n, c) = py_types[ret[0]] c_return = " %s c_retval;\n" % (ret[0]) if file == "python_accessor" and ret[2] != None: c_call = "\n c_retval = %s->%s;\n" % (args[0][0], ret[2]) else: c_call = "\n c_retval = %s(%s);\n" % (name, c_call); ret_convert = " py_retval = libvirt_%sWrap((%s) c_retval);\n" % (n,c) ret_convert = ret_convert + " return(py_retval);\n" elif py_return_types.has_key(ret[0]): (f, t, n, c) = py_return_types[ret[0]] c_return = " %s c_retval;\n" % (ret[0]) c_call = "\n c_retval = %s(%s);\n" % (name, c_call); ret_convert = " py_retval = libvirt_%sWrap((%s) c_retval);\n" % (n,c) ret_convert = ret_convert + " return(py_retval);\n" else: if skipped_types.has_key(ret[0]): return 0 if unknown_types.has_key(ret[0]): lst = unknown_types[ret[0]] lst.append(name) else: unknown_types[ret[0]] = [name] return -1 if cond != None and cond != "": include.write("#if %s\n" % cond) export.write("#if %s\n" % cond) output.write("#if %s\n" % cond) include.write("PyObject * ") include.write("libvirt_%s(PyObject *self, PyObject *args);\n" % (name)); export.write(" { (char *)\"%s\", libvirt_%s, METH_VARARGS, NULL },\n" % (name, name)) if file == "python": # Those have been manually generated if cond != None and cond != "": include.write("#endif\n"); export.write("#endif\n"); output.write("#endif\n"); return 1 if file == "python_accessor" and ret[0] != "void" and ret[2] is None: # Those have been manually generated if cond != None and cond != "": include.write("#endif\n"); export.write("#endif\n"); output.write("#endif\n"); return 1 output.write("PyObject *\n") output.write("libvirt_%s(PyObject *self ATTRIBUTE_UNUSED," % (name)) output.write(" PyObject *args") if format == "": output.write(" ATTRIBUTE_UNUSED") output.write(") {\n") if ret[0] != 'void': output.write(" PyObject *py_retval;\n") if c_return != "": output.write(c_return) if c_args != "": output.write(c_args) if format != "": output.write("\n if (!PyArg_ParseTuple(args, (char *)\"%s\"%s))\n" % (format, format_args)) output.write(" return(NULL);\n") if c_convert != "": output.write(c_convert) output.write("LIBVIRT_BEGIN_ALLOW_THREADS;\n"); output.write(c_call); output.write("LIBVIRT_END_ALLOW_THREADS;\n"); output.write(ret_convert) output.write("}\n\n") if cond != None and cond != "": include.write("#endif /* %s */\n" % cond) export.write("#endif /* %s */\n" % cond) output.write("#endif /* %s */\n" % cond) return 1 def buildStubs(): global py_types global py_return_types global unknown_types try: f = open(os.path.join(srcPref,"libvirt-api.xml")) data = f.read() (parser, target) = getparser() parser.feed(data) parser.close() except IOError, msg: try: f = open(os.path.join(srcPref,"..","docs","libvirt-api.xml")) data = f.read() (parser, target) = getparser() parser.feed(data) parser.close() except IOError, msg: print file, ":", msg sys.exit(1) n = len(functions.keys()) print "Found %d functions in libvirt-api.xml" % (n) py_types['pythonObject'] = ('O', "pythonObject", "pythonObject", "pythonObject") try: f = open(os.path.join(srcPref,"libvirt-python-api.xml")) data = f.read() (parser, target) = getparser() parser.feed(data) parser.close() except IOError, msg: print file, ":", msg print "Found %d functions in libvirt-python-api.xml" % ( len(functions.keys()) - n) nb_wrap = 0 failed = 0 skipped = 0 include = open("libvirt-py.h", "w") include.write("/* Generated */\n\n") export = open("libvirt-export.c", "w") export.write("/* Generated */\n\n") wrapper = open("libvirt-py.c", "w") wrapper.write("/* Generated */\n\n") wrapper.write("#include \n") wrapper.write("#include \n") wrapper.write("#include \"libvirt_wrap.h\"\n") wrapper.write("#include \"libvirt-py.h\"\n\n") for function in functions.keys(): ret = print_function_wrapper(function, wrapper, export, include) if ret < 0: failed = failed + 1 functions_failed.append(function) del functions[function] if ret == 0: skipped = skipped + 1 functions_skipped.append(function) del functions[function] if ret == 1: nb_wrap = nb_wrap + 1 include.close() export.close() wrapper.close() print "Generated %d wrapper functions" % nb_wrap print "Missing type converters: " for type in unknown_types.keys(): print "%s:%d " % (type, len(unknown_types[type])), print for f in functions_failed: print "ERROR: failed %s" % f if failed > 0: return -1 return 0 ####################################################################### # # This part writes part of the Python front-end classes based on # mapping rules between types and classes and also based on function # renaming to get consistent function names at the Python level # ####################################################################### # # The type automatically remapped to generated classes # classes_type = { "virDomainPtr": ("._o", "virDomain(self,_obj=%s)", "virDomain"), "virDomain *": ("._o", "virDomain(self, _obj=%s)", "virDomain"), "virNetworkPtr": ("._o", "virNetwork(self, _obj=%s)", "virNetwork"), "virNetwork *": ("._o", "virNetwork(self, _obj=%s)", "virNetwork"), "virStoragePoolPtr": ("._o", "virStoragePool(self, _obj=%s)", "virStoragePool"), "virStoragePool *": ("._o", "virStoragePool(self, _obj=%s)", "virStoragePool"), "virStorageVolPtr": ("._o", "virStorageVol(self, _obj=%s)", "virStorageVol"), "virStorageVol *": ("._o", "virStorageVol(self, _obj=%s)", "virStorageVol"), "virConnectPtr": ("._o", "virConnect(_obj=%s)", "virConnect"), "virConnect *": ("._o", "virConnect(_obj=%s)", "virConnect"), } converter_type = { } primary_classes = ["virDomain", "virNetwork", "virStoragePool", "virStorageVol", "virConnect"] classes_ancestor = { } classes_destructors = { "virDomain": "virDomainFree", "virNetwork": "virNetworkFree", "virStoragePool": "virStoragePoolFree", "virStorageVol": "virStorageVolFree", "virConnect": "virConnectClose", } functions_noexcept = { 'virDomainGetID': True, 'virDomainGetName': True, 'virNetworkGetName': True, 'virStoragePoolGetName': True, 'virStorageVolGetName': True, 'virStorageVolGetkey': True, } reference_keepers = { } function_classes = {} function_classes["None"] = [] function_post = { 'virDomainDestroy': "self._o = None", 'virNetworkDestroy': "self._o = None", 'virStoragePoolDestroy': "self._o = None", 'virStorageVolDestroy': "self._o = None", } # Functions returning an integral type which need special rules to # check for errors and raise exceptions. functions_int_exception_test = { 'virDomainGetMaxMemory': "%s == 0", } functions_int_default_test = "%s == -1" def is_integral_type (name): return not re.search ("^(unsigned)? ?(int|long)$", name) is None # Functions returning lists which need special rules to check for errors # and raise exceptions. functions_list_exception_test = { } functions_list_default_test = "%s is None" def is_list_type (name): return name[-1:] == "*" def nameFixup(name, classe, type, file): # avoid a desastrous clash listname = classe + "List" ll = len(listname) l = len(classe) if name[0:l] == listname: func = name[l:] func = string.lower(func[0:1]) + func[1:] elif name[0:16] == "virNetworkDefine": func = name[3:] func = string.lower(func[0:1]) + func[1:] elif name[0:16] == "virNetworkLookup": func = name[3:] func = string.lower(func[0:1]) + func[1:] elif name[0:20] == "virStoragePoolDefine": func = name[3:] func = string.lower(func[0:1]) + func[1:] elif name[0:20] == "virStoragePoolLookup": func = name[3:] func = string.lower(func[0:1]) + func[1:] elif name[0:19] == "virStorageVolDefine": func = name[3:] func = string.lower(func[0:1]) + func[1:] elif name[0:19] == "virStorageVolLookup": func = name[3:] func = string.lower(func[0:1]) + func[1:] elif name[0:12] == "virDomainGet": func = name[12:] func = string.lower(func[0:1]) + func[1:] elif name[0:9] == "virDomain": func = name[9:] func = string.lower(func[0:1]) + func[1:] elif name[0:13] == "virNetworkGet": func = name[13:] func = string.lower(func[0:1]) + func[1:] elif name[0:10] == "virNetwork": func = name[10:] func = string.lower(func[0:1]) + func[1:] elif name[0:17] == "virStoragePoolGet": func = name[17:] func = string.lower(func[0:1]) + func[1:] elif name[0:14] == "virStoragePool": func = name[14:] func = string.lower(func[0:1]) + func[1:] elif name[0:16] == "virStorageVolGet": func = name[16:] func = string.lower(func[0:1]) + func[1:] elif name[0:13] == "virStorageVol": func = name[13:] func = string.lower(func[0:1]) + func[1:] elif name[0:7] == "virNode": func = name[7:] func = string.lower(func[0:1]) + func[1:] elif name[0:10] == "virConnect": func = name[10:] func = string.lower(func[0:1]) + func[1:] elif name[0:3] == "xml": func = name[3:] func = string.lower(func[0:1]) + func[1:] else: func = name if func == "iD": func = "ID" if func == "uUID": func = "UUID" if func == "uUIDString": func = "UUIDString" if func == "oSType": func = "OSType" if func == "xMLDesc": func = "XMLDesc" return func def functionCompare(info1, info2): (index1, func1, name1, ret1, args1, file1) = info1 (index2, func2, name2, ret2, args2, file2) = info2 if file1 == file2: if func1 < func2: return -1 if func1 > func2: return 1 if file1 == " #define PRINTK2(args...) printf(args) #else #define PRINTK2(args...) #endif #ifdef EL_DEBUG #define PRINTK(args...) printf(args) #else #define PRINTK(args...) #endif #define outb(args...) mmio_outb(args) #define mmio_outb(value, addr) (*((volatile byte *)(addr)) = value) #define inb(args...) mmio_inb(args) #define mmio_inb(addr) (*((volatile byte *)(addr))) #define outw(args...) mmio_outw(args) #define mmio_outw(value, addr) (*((volatile word *)(addr)) = value) #define inw(args...) mmio_inw(args) #define mmio_inw(addr) (*((volatile word *)(addr))) #define outsw(args...) mmio_outsw(args) #define mmio_outsw(r,b,l) ({ int __i; \ word *__b2; \ __b2 = (word *) b; \ for (__i = 0; __i < l; __i++) { \ mmio_outw( *(__b2 + __i), r); \ } \ }) #define insw(args...) mmio_insw(args) #define mmio_insw(r,b,l) ({ int __i ; \ word *__b2; \ __b2 = (word *) b; \ for (__i = 0; __i < l; __i++) { \ *(__b2 + __i) = mmio_inw(r); \ mmio_inw(0); \ }; \ }) /*------------------------------------------------------------------------ . . The internal workings of the driver. If you are changing anything . here with the 3Com stuff, you should have the datasheet and know . what you are doing. . -------------------------------------------------------------------------*/ #define EL_BASE_ADDR 0x20000000 /* Offsets from base I/O address. */ #define EL3_DATA 0x00 #define EL3_TIMER 0x0a #define EL3_CMD 0x0e #define EL3_STATUS 0x0e #define EEPROM_READ 0x0080 #define EL3WINDOW(win_num) mmio_outw(SelectWindow + (win_num), EL_BASE_ADDR + EL3_CMD) /* The top five bits written to EL3_CMD are a command, the lower 11 bits are the parameter, if applicable. */ enum c509cmd { TotalReset = 0<<11, SelectWindow = 1<<11, StartCoax = 2<<11, RxDisable = 3<<11, RxEnable = 4<<11, RxReset = 5<<11, RxDiscard = 8<<11, TxEnable = 9<<11, TxDisable = 10<<11, TxReset = 11<<11, FakeIntr = 12<<11, AckIntr = 13<<11, SetIntrEnb = 14<<11, SetStatusEnb = 15<<11, SetRxFilter = 16<<11, SetRxThreshold = 17<<11, SetTxThreshold = 18<<11, SetTxStart = 19<<11, StatsEnable = 21<<11, StatsDisable = 22<<11, StopCoax = 23<<11, }; enum c509status { IntLatch = 0x0001, AdapterFailure = 0x0002, TxComplete = 0x0004, TxAvailable = 0x0008, RxComplete = 0x0010, RxEarly = 0x0020, IntReq = 0x0040, StatsFull = 0x0080, CmdBusy = 0x1000 }; /* The SetRxFilter command accepts the following classes: */ enum RxFilter { RxStation = 1, RxMulticast = 2, RxBroadcast = 4, RxProm = 8 }; /* Register window 1 offsets, the window used in normal operation. */ #define TX_FIFO 0x00 #define RX_FIFO 0x00 #define RX_STATUS 0x08 #define TX_STATUS 0x0B #define TX_FREE 0x0C /* Remaining free bytes in Tx buffer. */ /* Read a word from the EEPROM using the regular EEPROM access register. Assume that we are in register window zero. */ static word read_eeprom(dword ioaddr, int index) { int i; outw(EEPROM_READ + index, ioaddr + 0xa); /* Reading the eeprom takes 162 us */ for (i = 1620; i >= 0; i--) if ((inw(ioaddr + 10) & EEPROM_BUSY) == 0) break; return inw(ioaddr + 0xc); } static void el_get_mac_addr( unsigned char *mac_addr ) { int i; union { word w; unsigned char b[2]; } wrd; unsigned char old_window = inw( EL_BASE_ADDR + EL3_STATUS ) >> 13; GO_WINDOW(0); VX_BUSY_WAIT; for (i = 0; i < 3; i++) { wrd.w = read_eeprom(EL_BASE_ADDR, 0xa+i); #ifdef __BIG_ENDIAN mac_addr[2*i] = wrd.b[0]; mac_addr[2*i+1] = wrd.b[1]; #else mac_addr[2*i] = wrd.b[1]; mac_addr[2*i+1] = wrd.b[0]; #endif } GO_WINDOW(old_window); VX_BUSY_WAIT; } #if EL_DEBUG > 1 static void print_packet( byte * buf, int length ) { int i; int remainder; int lines; PRINTK2("Packet of length %d \n", length ); lines = length / 16; remainder = length % 16; for ( i = 0; i < lines ; i ++ ) { int cur; for ( cur = 0; cur < 8; cur ++ ) { byte a, b; a = *(buf ++ ); b = *(buf ++ ); PRINTK2("%02x%02x ", a, b ); } PRINTK2("\n"); } for ( i = 0; i < remainder/2 ; i++ ) { byte a, b; a = *(buf ++ ); b = *(buf ++ ); PRINTK2("%02x%02x ", a, b ); } PRINTK2("\n"); } #endif /* EL_DEBUG > 1 */ /************************************************************************** ETH_RESET - Reset adapter ***************************************************************************/ static void el_reset(bd_t *bd) { /*********************************************************** Reset 3Com 595 card *************************************************************/ /* QUICK HACK * - adjust timing for 3c589 * - enable io for PCMCIA */ outw(0x0004, 0xa0000018); udelay(100); outw(0x0041, 0x28010000); udelay(