#!/usr/bin/python -u # # generate python wrappers from the XML API description # functions = {} lxc_functions = {} qemu_functions = {} enums = {} # { enumType: { enumConstant: enumValue } } lxc_enums = {} # { enumType: { enumConstant: enumValue } } qemu_enums = {} # { enumType: { enumConstant: enumValue } } import os import sys import string import re quiet=True if __name__ == "__main__": # launched as a script srcPref = os.path.dirname(sys.argv[0]) if len(sys.argv) > 1: python = sys.argv[1] else: print "Python binary not specified" sys.exit(1) else: # imported srcPref = os.path.dirname(__file__) ####################################################################### # # That part if purely the API acquisition phase from the # libvirt API description # ####################################################################### import os import xml.sax debug = 0 def getparser(): # Attach parser to an unmarshalling object. return both objects. target = docParser() parser = xml.sax.make_parser() parser.setContentHandler(target) return parser, target class docParser(xml.sax.handler.ContentHandler): def __init__(self): self._methodname = None self._data = [] self.in_function = 0 self.startElement = self.start self.endElement = self.end self.characters = self.data 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 cdata(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 self.function_module= None if attrs.has_key('name'): self.function = attrs['name'] if attrs.has_key('file'): self.function_file = attrs['file'] if attrs.has_key('module'): self.function_module= attrs['module'] 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': # enums come from header files, hence virterror.h if (attrs['file'] == "libvirt" or attrs['file'] == "virterror"): enum(attrs['type'],attrs['name'],attrs['value']) elif attrs['file'] == "libvirt-lxc": lxc_enum(attrs['type'],attrs['name'],attrs['value']) elif attrs['file'] == "libvirt-qemu": qemu_enum(attrs['type'],attrs['name'],attrs['value']) def end(self, tag): if debug: print "end %s" % tag if tag == 'function': # fuctions come from source files, hence 'virerror.c' if self.function != None: if (self.function_module == "libvirt" or self.function_module == "virevent" or self.function_module == "virerror"): function(self.function, self.function_descr, self.function_return, self.function_args, self.function_file, self.function_module, self.function_cond) elif self.function_module == "libvirt-lxc": lxc_function(self.function, self.function_descr, self.function_return, self.function_args, self.function_file, self.function_module, self.function_cond) elif self.function_module == "libvirt-qemu": qemu_function(self.function, self.function_descr, self.function_return, self.function_args, self.function_file, self.function_module, self.function_cond) elif self.function_file == "python": function(self.function, self.function_descr, self.function_return, self.function_args, self.function_file, self.function_module, self.function_cond) elif self.function_file == "python-lxc": lxc_function(self.function, self.function_descr, self.function_return, self.function_args, self.function_file, self.function_module, self.function_cond) elif self.function_file == "python-qemu": qemu_function(self.function, self.function_descr, self.function_return, self.function_args, self.function_file, self.function_module, 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, module, cond): functions[name] = (desc, ret, args, file, module, cond) def qemu_function(name, desc, ret, args, file, module, cond): qemu_functions[name] = (desc, ret, args, file, module, cond) def lxc_function(name, desc, ret, args, file, module, cond): lxc_functions[name] = (desc, ret, args, file, module, cond) def enum(type, name, value): if not enums.has_key(type): enums[type] = {} if value == 'VIR_TYPED_PARAM_INT': value = 1 elif value == 'VIR_TYPED_PARAM_UINT': value = 2 elif value == 'VIR_TYPED_PARAM_LLONG': value = 3 elif value == 'VIR_TYPED_PARAM_ULLONG': value = 4 elif value == 'VIR_TYPED_PARAM_DOUBLE': value = 5 elif value == 'VIR_TYPED_PARAM_BOOLEAN': value = 6 elif value == 'VIR_DOMAIN_AFFECT_CURRENT': value = 0 elif value == 'VIR_DOMAIN_AFFECT_LIVE': value = 1 elif value == 'VIR_DOMAIN_AFFECT_CONFIG': value = 2 if name[-5:] != '_LAST': enums[type][name] = value def lxc_enum(type, name, value): if not lxc_enums.has_key(type): lxc_enums[type] = {} lxc_enums[type][name] = value def qemu_enum(type, name, value): if not qemu_enums.has_key(type): qemu_enums[type] = {} qemu_enums[type][name] = value ####################################################################### # # Some filtering rukes to drop functions/types which should not # be exposed as-is on the Python interface # ####################################################################### functions_failed = [] lxc_functions_failed = [] qemu_functions_failed = [] functions_skipped = [ "virConnectListDomains", ] lxc_functions_skipped = [] qemu_functions_skipped = [] skipped_modules = { } skipped_types = { # 'int *': "usually a return type", 'virConnectDomainEventCallback': "No function types in python", 'virConnectDomainEventGenericCallback': "No function types in python", 'virConnectDomainEventRTCChangeCallback': "No function types in python", 'virConnectDomainEventWatchdogCallback': "No function types in python", 'virConnectDomainEventIOErrorCallback': "No function types in python", 'virConnectDomainEventGraphicsCallback': "No function types in python", 'virStreamEventCallback': "No function types in python", 'virEventHandleCallback': "No function types in python", 'virEventTimeoutCallback': "No function types in python", 'virDomainBlockJobInfoPtr': "Not implemented yet", } ####################################################################### # # 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"), 'long long': ('L', None, "longlong", "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, "constcharPtr", "const char *"), 'size_t': ('n', None, "size_t", "size_t"), '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"), 'virInterfacePtr': ('O', "virInterface", "virInterfacePtr", "virInterfacePtr"), 'const virInterfacePtr': ('O', "virInterface", "virInterfacePtr", "virInterfacePtr"), 'virInterface *': ('O', "virInterface", "virInterfacePtr", "virInterfacePtr"), 'const virInterface *': ('O', "virInterface", "virInterfacePtr", "virInterfacePtr"), '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"), 'virNodeDevicePtr': ('O', "virNodeDevice", "virNodeDevicePtr", "virNodeDevicePtr"), 'const virNodeDevicePtr': ('O', "virNodeDevice", "virNodeDevicePtr", "virNodeDevicePtr"), 'virNodeDevice *': ('O', "virNodeDevice", "virNodeDevicePtr", "virNodeDevicePtr"), 'const virNodeDevice *': ('O', "virNodeDevice", "virNodeDevicePtr", "virNodeDevicePtr"), 'virSecretPtr': ('O', "virSecret", "virSecretPtr", "virSecretPtr"), 'const virSecretPtr': ('O', "virSecret", "virSecretPtr", "virSecretPtr"), 'virSecret *': ('O', "virSecret", "virSecretPtr", "virSecretPtr"), 'const virSecret *': ('O', "virSecret", "virSecretPtr", "virSecretPtr"), 'virNWFilterPtr': ('O', "virNWFilter", "virNWFilterPtr", "virNWFilterPtr"), 'const virNWFilterPtr': ('O', "virNWFilter", "virNWFilterPtr", "virNWFilterPtr"), 'virNWFilter *': ('O', "virNWFilter", "virNWFilterPtr", "virNWFilterPtr"), 'const virNWFilter *': ('O', "virNWFilter", "virNWFilterPtr", "virNWFilterPtr"), 'virStreamPtr': ('O', "virStream", "virStreamPtr", "virStreamPtr"), 'const virStreamPtr': ('O', "virStream", "virStreamPtr", "virStreamPtr"), 'virStream *': ('O', "virStream", "virStreamPtr", "virStreamPtr"), 'const virStream *': ('O', "virStream", "virStreamPtr", "virStreamPtr"), 'virDomainSnapshotPtr': ('O', "virDomainSnapshot", "virDomainSnapshotPtr", "virDomainSnapshotPtr"), 'const virDomainSnapshotPtr': ('O', "virDomainSnapshot", "virDomainSnapshotPtr", "virDomainSnapshotPtr"), 'virDomainSnapshot *': ('O', "virDomainSnapshot", "virDomainSnapshotPtr", "virDomainSnapshotPtr"), 'const virDomainSnapshot *': ('O', "virDomainSnapshot", "virDomainSnapshotPtr", "virDomainSnapshotPtr"), } py_return_types = { } unknown_types = {} foreign_encoding_args = ( ) ####################################################################### # # This part writes the C <-> Python stubs libvirt.[ch] and # the table libvirt-export.c to add when registrering the Python module # ####################################################################### # Class methods which are written by hand in libvirt.c but the Python-level # code is still automatically generated (so they are not in skip_function()). skip_impl = ( 'virConnectGetVersion', 'virConnectGetLibVersion', 'virConnectListDomainsID', 'virConnectListDefinedDomains', 'virConnectListNetworks', 'virConnectListDefinedNetworks', 'virConnectListSecrets', 'virConnectListInterfaces', 'virConnectListStoragePools', 'virConnectListDefinedStoragePools', 'virConnectListStorageVols', 'virConnectListDefinedStorageVols', 'virConnectListDefinedInterfaces', 'virConnectListNWFilters', 'virDomainSnapshotListNames', 'virDomainSnapshotListChildrenNames', 'virConnGetLastError', 'virGetLastError', 'virDomainGetInfo', 'virDomainGetState', 'virDomainGetControlInfo', 'virDomainGetBlockInfo', 'virDomainGetJobInfo', 'virDomainGetJobStats', 'virNodeGetInfo', 'virDomainGetUUID', 'virDomainGetUUIDString', 'virDomainLookupByUUID', 'virNetworkGetUUID', 'virNetworkGetUUIDString', 'virNetworkLookupByUUID', 'virDomainGetAutostart', 'virNetworkGetAutostart', 'virDomainBlockStats', 'virDomainInterfaceStats', 'virDomainMemoryStats', 'virNodeGetCellsFreeMemory', 'virDomainGetSchedulerType', 'virDomainGetSchedulerParameters', 'virDomainGetSchedulerParametersFlags', 'virDomainSetSchedulerParameters', 'virDomainSetSchedulerParametersFlags', 'virDomainSetBlkioParameters', 'virDomainGetBlkioParameters', 'virDomainSetMemoryParameters', 'virDomainGetMemoryParameters', 'virDomainSetNumaParameters', 'virDomainGetNumaParameters', 'virDomainGetVcpus', 'virDomainPinVcpu', 'virDomainPinVcpuFlags', 'virDomainGetVcpuPinInfo', 'virSecretGetValue', 'virSecretSetValue', 'virSecretGetUUID', 'virSecretGetUUIDString', 'virSecretLookupByUUID', 'virNWFilterGetUUID', 'virNWFilterGetUUIDString', 'virNWFilterLookupByUUID', 'virStoragePoolGetUUID', 'virStoragePoolGetUUIDString', 'virStoragePoolLookupByUUID', 'virStoragePoolGetInfo', 'virStorageVolGetInfo', 'virStoragePoolGetAutostart', 'virStoragePoolListVolumes', 'virDomainBlockPeek', 'virDomainMemoryPeek', 'virEventRegisterImpl', 'virNodeListDevices', 'virNodeDeviceListCaps', 'virConnectBaselineCPU', 'virDomainRevertToSnapshot', 'virDomainSendKey', 'virNodeGetCPUStats', 'virNodeGetMemoryStats', 'virDomainGetBlockJobInfo', 'virDomainMigrateGetMaxSpeed', 'virDomainBlockStatsFlags', 'virDomainSetBlockIoTune', 'virDomainGetBlockIoTune', 'virDomainSetInterfaceParameters', 'virDomainGetInterfaceParameters', 'virDomainGetCPUStats', 'virDomainGetDiskErrors', 'virNodeGetMemoryParameters', 'virNodeSetMemoryParameters', 'virNodeGetCPUMap', ) lxc_skip_impl = ( 'virDomainLxcOpenNamespace', ) qemu_skip_impl = ( 'virDomainQemuMonitorCommand', 'virDomainQemuAgentCommand', ) # 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 ? '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 'virDomainGetSecurityLabel', # Needs investigation... 'virDomainGetSecurityLabelList', # Needs investigation... 'virNodeGetSecurityModel', # Needs investigation... 'virConnectDomainEventRegister', # overridden in virConnect.py 'virConnectDomainEventDeregister', # overridden in virConnect.py 'virConnectDomainEventRegisterAny', # overridden in virConnect.py 'virConnectDomainEventDeregisterAny', # overridden in virConnect.py 'virSaveLastError', # We have our own python error wrapper 'virFreeError', # Only needed if we use virSaveLastError 'virConnectListAllDomains', # overridden in virConnect.py 'virDomainListAllSnapshots', # overridden in virDomain.py 'virDomainSnapshotListAllChildren', # overridden in virDomainSnapshot.py 'virConnectListAllStoragePools', # overridden in virConnect.py 'virStoragePoolListAllVolumes', # overridden in virStoragePool.py 'virConnectListAllNetworks', # overridden in virConnect.py 'virConnectListAllInterfaces', # overridden in virConnect.py 'virConnectListAllNodeDevices', # overridden in virConnect.py 'virConnectListAllNWFilters', # overridden in virConnect.py 'virConnectListAllSecrets', # overridden in virConnect.py 'virStreamRecvAll', # Pure python libvirt-override-virStream.py 'virStreamSendAll', # Pure python libvirt-override-virStream.py 'virStreamRecv', # overridden in libvirt-override-virStream.py 'virStreamSend', # overridden in libvirt-override-virStream.py 'virConnectUnregisterCloseCallback', # overriden in virConnect.py 'virConnectRegisterCloseCallback', # overriden in virConnect.py # 'Ref' functions have no use for bindings users. "virConnectRef", "virDomainRef", "virInterfaceRef", "virNetworkRef", "virNodeDeviceRef", "virSecretRef", "virNWFilterRef", "virStoragePoolRef", "virStorageVolRef", 'virStreamRef', # This functions shouldn't be called via the bindings (and even the docs # contain an explicit warning to that effect). The equivalent should be # implemented in pure python for each class "virDomainGetConnect", "virInterfaceGetConnect", "virNetworkGetConnect", "virSecretGetConnect", "virNWFilterGetConnect", "virStoragePoolGetConnect", "virStorageVolGetConnect", "virDomainSnapshotGetConnect", "virDomainSnapshotGetDomain", # only useful in C code, python code uses dict for typed parameters "virTypedParamsAddBoolean", "virTypedParamsAddDouble", "virTypedParamsAddFromString", "virTypedParamsAddInt", "virTypedParamsAddLLong", "virTypedParamsAddString", "virTypedParamsAddUInt", "virTypedParamsAddULLong", "virTypedParamsClear", "virTypedParamsFree", "virTypedParamsGet", "virTypedParamsGetBoolean", "virTypedParamsGetDouble", "virTypedParamsGetInt", "virTypedParamsGetLLong", "virTypedParamsGetString", "virTypedParamsGetUInt", "virTypedParamsGetULLong", ) lxc_skip_function = ( "virDomainLxcEnterNamespace", ) qemu_skip_function = ( #"virDomainQemuAttach", ) # Generate C code, but skip python impl function_skip_python_impl = ( "virStreamFree", # Needed in custom virStream __del__, but free shouldn't # be exposed in bindings ) lxc_function_skip_python_impl = () qemu_function_skip_python_impl = () function_skip_index_one = ( "virDomainRevertToSnapshot", ) def print_function_wrapper(module, name, output, export, include): global py_types global unknown_types global functions global lxc_functions global qemu_functions global skipped_modules global function_skip_python_impl try: if module == "libvirt": (desc, ret, args, file, mod, cond) = functions[name] if module == "libvirt-lxc": (desc, ret, args, file, mod, cond) = lxc_functions[name] if module == "libvirt-qemu": (desc, ret, args, file, mod, cond) = qemu_functions[name] except: print "failed to get function %s infos" % name return if skipped_modules.has_key(module): return 0 if module == "libvirt": if name in skip_function: return 0 if name in skip_impl: # Don't delete the function entry in the caller. return 1 elif module == "libvirt-lxc": if name in lxc_skip_function: return 0 if name in lxc_skip_impl: # Don't delete the function entry in the caller. return 1 elif module == "libvirt-qemu": if name in qemu_skip_function: return 0 if name in qemu_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 VIR_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 * ") if module == "libvirt": include.write("libvirt_%s(PyObject *self, PyObject *args);\n" % (name)) export.write(" { (char *)\"%s\", libvirt_%s, METH_VARARGS, NULL },\n" % (name, name)) elif module == "libvirt-lxc": include.write("libvirt_lxc_%s(PyObject *self, PyObject *args);\n" % (name)) export.write(" { (char *)\"%s\", libvirt_lxc_%s, METH_VARARGS, NULL },\n" % (name, name)) elif module == "libvirt-qemu": include.write("libvirt_qemu_%s(PyObject *self, PyObject *args);\n" % (name)) export.write(" { (char *)\"%s\", libvirt_qemu_%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") if module == "libvirt": output.write("libvirt_%s(PyObject *self ATTRIBUTE_UNUSED," % (name)) elif module == "libvirt-lxc": output.write("libvirt_lxc_%s(PyObject *self ATTRIBUTE_UNUSED," % (name)) elif module == "libvirt-qemu": output.write("libvirt_qemu_%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 + "\n") output.write(" LIBVIRT_BEGIN_ALLOW_THREADS;") 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) if module == "libvirt": if name in function_skip_python_impl: return 0 elif module == "libvirt-lxc": if name in lxc_function_skip_python_impl: return 0 elif module == "libvirt-qemu": if name in qemu_function_skip_python_impl: return 0 return 1 def buildStubs(module): global py_types global py_return_types global unknown_types if module not in ["libvirt", "libvirt-qemu", "libvirt-lxc"]: print "ERROR: Unknown module type: %s" % module return None if module == "libvirt": funcs = functions funcs_failed = functions_failed funcs_skipped = functions_skipped elif module == "libvirt-lxc": funcs = lxc_functions funcs_failed = lxc_functions_failed funcs_skipped = functions_skipped elif module == "libvirt-qemu": funcs = qemu_functions funcs_failed = qemu_functions_failed funcs_skipped = functions_skipped api_xml = "%s-api.xml" % module try: f = open(os.path.join(srcPref,api_xml)) data = f.read() (parser, target) = getparser() parser.feed(data) parser.close() except IOError, msg: try: f = open(os.path.join(srcPref,"..","docs",api_xml)) data = f.read() (parser, target) = getparser() parser.feed(data) parser.close() except IOError, msg: print file, ":", msg sys.exit(1) n = len(funcs.keys()) if not quiet: print "Found %d functions in %s" % ((n), api_xml) override_api_xml = "%s-override-api.xml" % module py_types['pythonObject'] = ('O', "pythonObject", "pythonObject", "pythonObject") try: f = open(os.path.join(srcPref, override_api_xml)) data = f.read() (parser, target) = getparser() parser.feed(data) parser.close() except IOError, msg: print file, ":", msg if not quiet: # XXX: This is not right, same function already in @functions # will be overwritten. print "Found %d functions in %s" % ((len(funcs.keys()) - n), override_api_xml) nb_wrap = 0 failed = 0 skipped = 0 header_file = "%s.h" % module export_file = "%s-export.c" % module wrapper_file = "%s.c" % module include = open(header_file, "w") include.write("/* Generated */\n\n") export = open(export_file, "w") export.write("/* Generated */\n\n") wrapper = open(wrapper_file, "w") wrapper.write("/* Generated by generator.py */\n\n") wrapper.write("#include \n") wrapper.write("#include \n") wrapper.write("#include \n") wrapper.write("#include \"typewrappers.h\"\n") wrapper.write("#include \"" + module + ".h\"\n\n") for function in funcs.keys(): # Skip the functions which are not for the module ret = print_function_wrapper(module, function, wrapper, export, include) if ret < 0: failed = failed + 1 funcs_failed.append(function) del funcs[function] if ret == 0: skipped = skipped + 1 funcs_skipped.append(function) del funcs[function] if ret == 1: nb_wrap = nb_wrap + 1 include.close() export.close() wrapper.close() if not quiet: print "Generated %d wrapper functions" % nb_wrap if unknown_types: print "Missing type converters: " for type in unknown_types.keys(): print "%s:%d " % (type, len(unknown_types[type])), for f in funcs_failed: print "ERROR: failed %s" % f if failed > 0: return -1 if len(unknown_types) > 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"), "virInterfacePtr": ("._o", "virInterface(self, _obj=%s)", "virInterface"), "virInterface *": ("._o", "virInterface(self, _obj=%s)", "virInterface"), "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"), "virNodeDevicePtr": ("._o", "virNodeDevice(self, _obj=%s)", "virNodeDevice"), "virNodeDevice *": ("._o", "virNodeDevice(self, _obj=%s)", "virNodeDevice"), "virSecretPtr": ("._o", "virSecret(self, _obj=%s)", "virSecret"), "virSecret *": ("._o", "virSecret(self, _obj=%s)", "virSecret"), "virNWFilterPtr": ("._o", "virNWFilter(self, _obj=%s)", "virNWFilter"), "virNWFilter *": ("._o", "virNWFilter(self, _obj=%s)", "virNWFilter"), "virStreamPtr": ("._o", "virStream(self, _obj=%s)", "virStream"), "virStream *": ("._o", "virStream(self, _obj=%s)", "virStream"), "virConnectPtr": ("._o", "virConnect(_obj=%s)", "virConnect"), "virConnect *": ("._o", "virConnect(_obj=%s)", "virConnect"), "virDomainSnapshotPtr": ("._o", "virDomainSnapshot(self,_obj=%s)", "virDomainSnapshot"), "virDomainSnapshot *": ("._o", "virDomainSnapshot(self, _obj=%s)", "virDomainSnapshot"), } converter_type = { } primary_classes = ["virDomain", "virNetwork", "virInterface", "virStoragePool", "virStorageVol", "virConnect", "virNodeDevice", "virSecret", "virNWFilter", "virStream", "virDomainSnapshot"] classes_ancestor = { } classes_destructors = { "virDomain": "virDomainFree", "virNetwork": "virNetworkFree", "virInterface": "virInterfaceFree", "virStoragePool": "virStoragePoolFree", "virStorageVol": "virStorageVolFree", "virNodeDevice" : "virNodeDeviceFree", "virSecret": "virSecretFree", "virNWFilter": "virNWFilterFree", "virDomainSnapshot": "virDomainSnapshotFree", # We hand-craft __del__ for this one #"virStream": "virStreamFree", } class_skip_connect_impl = { "virConnect" : True, } class_domain_impl = { "virDomainSnapshot": True, } functions_noexcept = { 'virDomainGetID': True, 'virDomainGetName': True, 'virNetworkGetName': True, 'virInterfaceGetName': True, 'virStoragePoolGetName': True, 'virStorageVolGetName': True, 'virStorageVolGetkey': True, 'virNodeDeviceGetName': True, 'virNodeDeviceGetParent': True, 'virSecretGetUsageType': True, 'virSecretGetUsageID': True, 'virNWFilterGetName': True, } reference_keepers = { } function_classes = {} function_classes["None"] = [] function_post = {} # 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): whitelist = [ "virDomainBlockStats", "virDomainInterfaceStats" ] return name[-1:] == "*" or name in whitelist 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:19] == "virNetworkCreateXML": 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:18] == "virInterfaceDefine": func = name[3:] func = string.lower(func[0:1]) + func[1:] elif name[0:21] == "virInterfaceCreateXML": func = name[3:] func = string.lower(func[0:1]) + func[1:] elif name[0:18] == "virInterfaceLookup": func = name[3:] func = string.lower(func[0:1]) + func[1:] elif name[0:15] == "virSecretDefine": func = name[3:] func = string.lower(func[0:1]) + func[1:] elif name[0:15] == "virSecretLookup": func = name[3:] func = string.lower(func[0:1]) + func[1:] elif name[0:17] == "virNWFilterDefine": func = name[3:] func = string.lower(func[0:3]) + func[3:] elif name[0:17] == "virNWFilterLookup": func = name[3:] func = string.lower(func[0:3]) + func[3:] elif name[0:20] == "virStoragePoolDefine": func = name[3:] func = string.lower(func[0:1]) + func[1:] elif name[0:23] == "virStoragePoolCreateXML": 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:20] == "virDomainGetCPUStats": func = name[9:] 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:29] == "virDomainSnapshotLookupByName": func = name[9:] func = string.lower(func[0:1]) + func[1:] elif name[0:26] == "virDomainSnapshotListNames": func = name[9:] func = string.lower(func[0:1]) + func[1:] elif name[0:28] == "virDomainSnapshotNumChildren": func = name[17:] func = string.lower(func[0:1]) + func[1:] elif name[0:20] == "virDomainSnapshotNum": func = name[9:] func = string.lower(func[0:1]) + func[1:] elif name[0:26] == "virDomainSnapshotCreateXML": func = name[9:] func = string.lower(func[0:1]) + func[1:] elif name[0:24] == "virDomainSnapshotCurrent": func = name[9:] func = string.lower(func[0:1]) + func[1:] elif name[0:17] == "virDomainSnapshot": func = name[17:] 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:15] == "virInterfaceGet": func = name[15:] func = string.lower(func[0:1]) + func[1:] elif name[0:12] == "virInterface": func = name[12:] func = string.lower(func[0:1]) + func[1:] elif name[0:12] == 'virSecretGet': func = name[12:] func = string.lower(func[0:1]) + func[1:] elif name[0:9] == 'virSecret': func = name[9:] func = string.lower(func[0:1]) + func[1:] elif name[0:14] == 'virNWFilterGet': func = name[14:] func = string.lower(func[0:1]) + func[1:] elif name[0:11] == 'virNWFilter': func = name[11:] func = string.lower(func[0:1]) + func[1:] elif name[0:12] == 'virStreamNew': func = "newStream" elif name[0:9] == 'virStream': func = name[9:] 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:13] == "virNodeDevice": if name[13:16] == "Get": func = string.lower(name[16]) + name[17:] elif name[13:19] == "Lookup" or name[13:19] == "Create": func = string.lower(name[3]) + name[4:] else: func = string.lower(name[13]) + name[14:] 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" if func == "mACString": func = "MACString" return func def functionCompare(info1, info2): (index1, func1, name1, ret1, args1, file1, mod1) = info1 (index2, func2, name2, ret2, args2, file2, mod2) = info2 if file1 == file2: if func1 < func2: return -1 if func1 > func2: return 1 if file1 == "python_accessor": return -1 if file2 == "python_accessor": return 1 if file1 < file2: return -1 if file1 > file2: return 1 return 0 def writeDoc(module, name, args, indent, output): if module == "libvirt": funcs = functions elif module == "libvirt-lxc": funcs = lxc_functions elif module == "libvirt-qemu": funcs = qemu_functions if funcs[name][0] is None or funcs[name][0] == "": return val = funcs[name][0] val = string.replace(val, "NULL", "None") output.write(indent) output.write('"""') i = string.find(val, "\n") while i >= 0: str = val[0:i+1] val = val[i+1:] output.write(str) i = string.find(val, "\n") output.write(indent) output.write(val) output.write(' """\n') def buildWrappers(module): global ctypes global py_types global py_return_types global unknown_types global functions global function_classes global classes_type global classes_list global converter_type global primary_classes global converter_type global classes_ancestor global converter_type global primary_classes global classes_destructors global functions_noexcept if not module == "libvirt": print "ERROR: Unknown module type: %s" % module return None for type in classes_type.keys(): function_classes[classes_type[type][2]] = [] # # Build the list of C types to look for ordered to start # with primary classes # ctypes = [] classes_list = [] ctypes_processed = {} classes_processed = {} for classe in primary_classes: classes_list.append(classe) classes_processed[classe] = () for type in classes_type.keys(): tinfo = classes_type[type] if tinfo[2] == classe: ctypes.append(type) ctypes_processed[type] = () for type in classes_type.keys(): if ctypes_processed.has_key(type): continue tinfo = classes_type[type] if not classes_processed.has_key(tinfo[2]): classes_list.append(tinfo[2]) classes_processed[tinfo[2]] = () ctypes.append(type) ctypes_processed[type] = () for name in functions.keys(): found = 0 (desc, ret, args, file, mod, cond) = functions[name] for type in ctypes: classe = classes_type[type][2] if name[0:3] == "vir" and len(args) >= 1 and args[0][1] == type: found = 1 func = nameFixup(name, classe, type, file) info = (0, func, name, ret, args, file, mod) function_classes[classe].append(info) elif name[0:3] == "vir" and len(args) >= 2 and args[1][1] == type \ and file != "python_accessor" and not name in function_skip_index_one: found = 1 func = nameFixup(name, classe, type, file) info = (1, func, name, ret, args, file, mod) function_classes[classe].append(info) if found == 1: continue func = nameFixup(name, "None", file, file) info = (0, func, name, ret, args, file, mod) function_classes['None'].append(info) classes_file = "%s.py" % module extra_file = os.path.join(srcPref, "%s-override.py" % module) extra = None classes = open(classes_file, "w") if os.path.exists(extra_file): extra = open(extra_file, "r") classes.write("#! " + python + " -i\n") classes.write("#\n") classes.write("# WARNING WARNING WARNING WARNING\n") classes.write("#\n") classes.write("# This file is automatically written by generator.py. Any changes\n") classes.write("# made here will be lost.\n") classes.write("#\n") classes.write("# To change the manually written methods edit " + module + "-override.py\n") classes.write("# To change the automatically written methods edit generator.py\n") classes.write("#\n") classes.write("# WARNING WARNING WARNING WARNING\n") classes.write("#\n") if extra != None: classes.writelines(extra.readlines()) classes.write("#\n") classes.write("# WARNING WARNING WARNING WARNING\n") classes.write("#\n") classes.write("# Automatically written part of python bindings for libvirt\n") classes.write("#\n") classes.write("# WARNING WARNING WARNING WARNING\n") if extra != None: extra.close() if function_classes.has_key("None"): flist = function_classes["None"] flist.sort(functionCompare) oldfile = "" for info in flist: (index, func, name, ret, args, file, mod) = info if file != oldfile: classes.write("#\n# Functions from module %s\n#\n\n" % file) oldfile = file classes.write("def %s(" % func) n = 0 for arg in args: if n != 0: classes.write(", ") classes.write("%s" % arg[0]) n = n + 1 classes.write("):\n") writeDoc(module, name, args, ' ', classes) for arg in args: if classes_type.has_key(arg[1]): classes.write(" if %s is None: %s__o = None\n" % (arg[0], arg[0])) classes.write(" else: %s__o = %s%s\n" % (arg[0], arg[0], classes_type[arg[1]][0])) if ret[0] != "void": classes.write(" ret = ") else: classes.write(" ") classes.write("libvirtmod.%s(" % name) n = 0 for arg in args: if n != 0: classes.write(", ") classes.write("%s" % arg[0]) if classes_type.has_key(arg[1]): classes.write("__o") n = n + 1 classes.write(")\n") if ret[0] != "void": if classes_type.has_key(ret[0]): # # Raise an exception # if functions_noexcept.has_key(name): classes.write(" if ret is None:return None\n") else: classes.write( " if ret is None:raise libvirtError('%s() failed')\n" % (name)) classes.write(" return ") classes.write(classes_type[ret[0]][1] % ("ret")) classes.write("\n") # For functions returning an integral type there are # several things that we can do, depending on the # contents of functions_int_*: elif is_integral_type (ret[0]): if not functions_noexcept.has_key (name): if functions_int_exception_test.has_key (name): test = functions_int_exception_test[name] else: test = functions_int_default_test classes.write ((" if " + test + ": raise libvirtError ('%s() failed')\n") % ("ret", name)) classes.write(" return ret\n") elif is_list_type (ret[0]): if not functions_noexcept.has_key (name): if functions_list_exception_test.has_key (name): test = functions_list_exception_test[name] else: test = functions_list_default_test classes.write ((" if " + test + ": raise libvirtError ('%s() failed')\n") % ("ret", name)) classes.write(" return ret\n") else: classes.write(" return ret\n") classes.write("\n") for classname in classes_list: if classname == "None": pass else: if classes_ancestor.has_key(classname): classes.write("class %s(%s):\n" % (classname, classes_ancestor[classname])) classes.write(" def __init__(self, _obj=None):\n") if reference_keepers.has_key(classname): rlist = reference_keepers[classname] for ref in rlist: classes.write(" self.%s = None\n" % ref[1]) classes.write(" self._o = _obj\n") classes.write(" %s.__init__(self, _obj=_obj)\n\n" % ( classes_ancestor[classname])) else: classes.write("class %s(object):\n" % (classname)) if classname in [ "virDomain", "virNetwork", "virInterface", "virStoragePool", "virStorageVol", "virNodeDevice", "virSecret","virStream", "virNWFilter" ]: classes.write(" def __init__(self, conn, _obj=None):\n") elif classname in [ 'virDomainSnapshot' ]: classes.write(" def __init__(self, dom, _obj=None):\n") else: classes.write(" def __init__(self, _obj=None):\n") if reference_keepers.has_key(classname): list = reference_keepers[classname] for ref in list: classes.write(" self.%s = None\n" % ref[1]) if classname in [ "virDomain", "virNetwork", "virInterface", "virNodeDevice", "virSecret", "virStream", "virNWFilter" ]: classes.write(" self._conn = conn\n") elif classname in [ "virStorageVol", "virStoragePool" ]: classes.write(" self._conn = conn\n" + \ " if not isinstance(conn, virConnect):\n" + \ " self._conn = conn._conn\n") elif classname in [ "virDomainSnapshot" ]: classes.write(" self._dom = dom\n") classes.write(" self._conn = dom.connect()\n") classes.write(" if _obj != None:self._o = _obj;return\n") classes.write(" self._o = None\n\n") destruct=None if classes_destructors.has_key(classname): classes.write(" def __del__(self):\n") classes.write(" if self._o != None:\n") classes.write(" libvirtmod.%s(self._o)\n" % classes_destructors[classname]) classes.write(" self._o = None\n\n") destruct=classes_destructors[classname] if not class_skip_connect_impl.has_key(classname): # Build python safe 'connect' method classes.write(" def connect(self):\n") classes.write(" return self._conn\n\n") if class_domain_impl.has_key(classname): classes.write(" def domain(self):\n") classes.write(" return self._dom\n\n") flist = function_classes[classname] flist.sort(functionCompare) oldfile = "" for info in flist: (index, func, name, ret, args, file, mod) = info # # Do not provide as method the destructors for the class # to avoid double free # if name == destruct: continue if file != oldfile: if file == "python_accessor": classes.write(" # accessors for %s\n" % (classname)) else: classes.write(" #\n") classes.write(" # %s functions from module %s\n" % ( classname, file)) classes.write(" #\n\n") oldfile = file classes.write(" def %s(self" % func) n = 0 for arg in args: if n != index: classes.write(", %s" % arg[0]) n = n + 1 classes.write("):\n") writeDoc(module, name, args, ' ', classes) n = 0 for arg in args: if classes_type.has_key(arg[1]): if n != index: classes.write(" if %s is None: %s__o = None\n" % (arg[0], arg[0])) classes.write(" else: %s__o = %s%s\n" % (arg[0], arg[0], classes_type[arg[1]][0])) n = n + 1 if ret[0] != "void": classes.write(" ret = ") else: classes.write(" ") n = 0 classes.write("libvirtmod.%s(" % name) for arg in args: if n != 0: classes.write(", ") if n != index: classes.write("%s" % arg[0]) if classes_type.has_key(arg[1]): classes.write("__o") else: classes.write("self") if classes_type.has_key(arg[1]): classes.write(classes_type[arg[1]][0]) n = n + 1 classes.write(")\n") if name == "virConnectClose": classes.write(" self._o = None\n") # For functions returning object types: if ret[0] != "void": if classes_type.has_key(ret[0]): # # Raise an exception # if functions_noexcept.has_key(name): classes.write( " if ret is None:return None\n") else: if classname == "virConnect": classes.write( " if ret is None:raise libvirtError('%s() failed', conn=self)\n" % (name)) elif classname == "virDomain": classes.write( " if ret is None:raise libvirtError('%s() failed', dom=self)\n" % (name)) elif classname == "virNetwork": classes.write( " if ret is None:raise libvirtError('%s() failed', net=self)\n" % (name)) elif classname == "virInterface": classes.write( " if ret is None:raise libvirtError('%s() failed', net=self)\n" % (name)) elif classname == "virStoragePool": classes.write( " if ret is None:raise libvirtError('%s() failed', pool=self)\n" % (name)) elif classname == "virStorageVol": classes.write( " if ret is None:raise libvirtError('%s() failed', vol=self)\n" % (name)) elif classname == "virDomainSnapshot": classes.write( " if ret is None:raise libvirtError('%s() failed', dom=self._dom)\n" % (name)) else: classes.write( " if ret is None:raise libvirtError('%s() failed')\n" % (name)) # # generate the returned class wrapper for the object # classes.write(" __tmp = ") classes.write(classes_type[ret[0]][1] % ("ret")) classes.write("\n") # # Sometime one need to keep references of the source # class in the returned class object. # See reference_keepers for the list # tclass = classes_type[ret[0]][2] if reference_keepers.has_key(tclass): list = reference_keepers[tclass] for pref in list: if pref[0] == classname: classes.write(" __tmp.%s = self\n" % pref[1]) # Post-processing - just before we return. if function_post.has_key(name): classes.write(" %s\n" % (function_post[name])) # # return the class # classes.write(" return __tmp\n") elif converter_type.has_key(ret[0]): # # Raise an exception # if functions_noexcept.has_key(name): classes.write( " if ret is None:return None") # Post-processing - just before we return. if function_post.has_key(name): classes.write(" %s\n" % (function_post[name])) classes.write(" return ") classes.write(converter_type[ret[0]] % ("ret")) classes.write("\n") # For functions returning an integral type there # are several things that we can do, depending on # the contents of functions_int_*: elif is_integral_type (ret[0]): if not functions_noexcept.has_key (name): if functions_int_exception_test.has_key (name): test = functions_int_exception_test[name] else: test = functions_int_default_test if classname == "virConnect": classes.write ((" if " + test + ": raise libvirtError ('%s() failed', conn=self)\n") % ("ret", name)) elif classname == "virDomain": classes.write ((" if " + test + ": raise libvirtError ('%s() failed', dom=self)\n") % ("ret", name)) elif classname == "virNetwork": classes.write ((" if " + test + ": raise libvirtError ('%s() failed', net=self)\n") % ("ret", name)) elif classname == "virInterface": classes.write ((" if " + test + ": raise libvirtError ('%s() failed', net=self)\n") % ("ret", name)) elif classname == "virStoragePool": classes.write ((" if " + test + ": raise libvirtError ('%s() failed', pool=self)\n") % ("ret", name)) elif classname == "virStorageVol": classes.write ((" if " + test + ": raise libvirtError ('%s() failed', vol=self)\n") % ("ret", name)) else: classes.write ((" if " + test + ": raise libvirtError ('%s() failed')\n") % ("ret", name)) # Post-processing - just before we return. if function_post.has_key(name): classes.write(" %s\n" % (function_post[name])) classes.write (" return ret\n") elif is_list_type (ret[0]): if not functions_noexcept.has_key (name): if functions_list_exception_test.has_key (name): test = functions_list_exception_test[name] else: test = functions_list_default_test if classname == "virConnect": classes.write ((" if " + test + ": raise libvirtError ('%s() failed', conn=self)\n") % ("ret", name)) elif classname == "virDomain": classes.write ((" if " + test + ": raise libvirtError ('%s() failed', dom=self)\n") % ("ret", name)) elif classname == "virNetwork": classes.write ((" if " + test + ": raise libvirtError ('%s() failed', net=self)\n") % ("ret", name)) elif classname == "virInterface": classes.write ((" if " + test + ": raise libvirtError ('%s() failed', net=self)\n") % ("ret", name)) elif classname == "virStoragePool": classes.write ((" if " + test + ": raise libvirtError ('%s() failed', pool=self)\n") % ("ret", name)) elif classname == "virStorageVol": classes.write ((" if " + test + ": raise libvirtError ('%s() failed', vol=self)\n") % ("ret", name)) else: classes.write ((" if " + test + ": raise libvirtError ('%s() failed')\n") % ("ret", name)) # Post-processing - just before we return. if function_post.has_key(name): classes.write(" %s\n" % (function_post[name])) classes.write (" return ret\n") else: # Post-processing - just before we return. if function_post.has_key(name): classes.write(" %s\n" % (function_post[name])) classes.write(" return ret\n") classes.write("\n") # Append ".py" to class def, iff it exists try: extra = open(os.path.join(srcPref,"libvirt-override-" + classname + ".py"), "r") classes.write (" #\n") classes.write (" # %s methods from %s.py (hand coded)\n" % (classname,classname)) classes.write (" #\n") classes.writelines(extra.readlines()) classes.write("\n") extra.close() except: pass # # Generate enum constants # for type,enum in enums.items(): classes.write("# %s\n" % type) items = enum.items() items.sort(lambda i1,i2: cmp(long(i1[1]),long(i2[1]))) for name,value in items: classes.write("%s = %s\n" % (name,value)) classes.write("\n") classes.close() def qemuBuildWrappers(module): global qemu_functions if not module == "libvirt-qemu": print "ERROR: only libvirt-qemu is supported" return None extra_file = os.path.join(srcPref, "%s-override.py" % module) extra = None fd = open("libvirt_qemu.py", "w") if os.path.exists(extra_file): extra = open(extra_file, "r") fd.write("#! " + python + " -i\n") fd.write("#\n") fd.write("# WARNING WARNING WARNING WARNING\n") fd.write("#\n") fd.write("# This file is automatically written by generator.py. Any changes\n") fd.write("# made here will be lost.\n") fd.write("#\n") fd.write("# To change the manually written methods edit " + module + "-override.py\n") fd.write("# To change the automatically written methods edit generator.py\n") fd.write("#\n") fd.write("# WARNING WARNING WARNING WARNING\n") fd.write("#\n") if extra != None: fd.writelines(extra.readlines()) fd.write("#\n") fd.write("# WARNING WARNING WARNING WARNING\n") fd.write("#\n") fd.write("# Automatically written part of python bindings for libvirt\n") fd.write("#\n") fd.write("# WARNING WARNING WARNING WARNING\n") if extra != None: extra.close() fd.write("try:\n") fd.write(" import libvirtmod_qemu\n") fd.write("except ImportError, lib_e:\n") fd.write(" try:\n") fd.write(" import cygvirtmod_qemu as libvirtmod_qemu\n") fd.write(" except ImportError, cyg_e:\n") fd.write(" if str(cyg_e).count(\"No module named\"):\n") fd.write(" raise lib_e\n\n") fd.write("import libvirt\n\n") fd.write("#\n# Functions from module %s\n#\n\n" % module) # # Generate functions directly, no classes # for name in qemu_functions.keys(): func = nameFixup(name, 'None', None, None) (desc, ret, args, file, mod, cond) = qemu_functions[name] fd.write("def %s(" % func) n = 0 for arg in args: if n != 0: fd.write(", ") fd.write("%s" % arg[0]) n = n + 1 fd.write("):\n") writeDoc(module, name, args, ' ', fd) if ret[0] != "void": fd.write(" ret = ") else: fd.write(" ") fd.write("libvirtmod_qemu.%s(" % name) n = 0 conn = None for arg in args: if arg[1] == "virConnectPtr": conn = arg[0] if n != 0: fd.write(", ") if arg[1] in ["virDomainPtr", "virConnectPtr"]: # FIXME: This might have problem if the function # has multiple args which are objects. fd.write("%s.%s" % (arg[0], "_o")) else: fd.write("%s" % arg[0]) n = n + 1 fd.write(")\n") if ret[0] != "void": fd.write(" if ret is None: raise libvirt.libvirtError('" + name + "() failed')\n") if ret[0] == "virDomainPtr": fd.write(" __tmp = virDomain(" + conn + ",_obj=ret)\n") fd.write(" return __tmp\n") else: fd.write(" return ret\n") fd.write("\n") # # Generate enum constants # for type,enum in qemu_enums.items(): fd.write("# %s\n" % type) items = enum.items() items.sort(lambda i1,i2: cmp(long(i1[1]),long(i2[1]))) for name,value in items: fd.write("%s = %s\n" % (name,value)) fd.write("\n") fd.close() def lxcBuildWrappers(module): global lxc_functions if not module == "libvirt-lxc": print "ERROR: only libvirt-lxc is supported" return None extra_file = os.path.join(srcPref, "%s-override.py" % module) extra = None fd = open("libvirt_lxc.py", "w") if os.path.exists(extra_file): extra = open(extra_file, "r") fd.write("#! " + python + " -i\n") fd.write("#\n") fd.write("# WARNING WARNING WARNING WARNING\n") fd.write("#\n") fd.write("# This file is automatically written by generator.py. Any changes\n") fd.write("# made here will be lost.\n") fd.write("#\n") fd.write("# To change the manually written methods edit " + module + "-override.py\n") fd.write("# To change the automatically written methods edit generator.py\n") fd.write("#\n") fd.write("# WARNING WARNING WARNING WARNING\n") fd.write("#\n") if extra != None: fd.writelines(extra.readlines()) fd.write("#\n") fd.write("# WARNING WARNING WARNING WARNING\n") fd.write("#\n") fd.write("# Automatically written part of python bindings for libvirt\n") fd.write("#\n") fd.write("# WARNING WARNING WARNING WARNING\n") if extra != None: extra.close() fd.write("try:\n") fd.write(" import libvirtmod_lxc\n") fd.write("except ImportError, lib_e:\n") fd.write(" try:\n") fd.write(" import cygvirtmod_lxc as libvirtmod_lxc\n") fd.write(" except ImportError, cyg_e:\n") fd.write(" if str(cyg_e).count(\"No module named\"):\n") fd.write(" raise lib_e\n\n") fd.write("import libvirt\n\n") fd.write("#\n# Functions from module %s\n#\n\n" % module) # # Generate functions directly, no classes # for name in lxc_functions.keys(): func = nameFixup(name, 'None', None, None) (desc, ret, args, file, mod, cond) = lxc_functions[name] fd.write("def %s(" % func) n = 0 for arg in args: if n != 0: fd.write(", ") fd.write("%s" % arg[0]) n = n + 1 fd.write("):\n") writeDoc(module, name, args, ' ', fd) if ret[0] != "void": fd.write(" ret = ") else: fd.write(" ") fd.write("libvirtmod_lxc.%s(" % name) n = 0 conn = None for arg in args: if arg[1] == "virConnectPtr": conn = arg[0] if n != 0: fd.write(", ") if arg[1] in ["virDomainPtr", "virConnectPtr"]: # FIXME: This might have problem if the function # has multiple args which are objects. fd.write("%s.%s" % (arg[0], "_o")) else: fd.write("%s" % arg[0]) n = n + 1 fd.write(")\n") if ret[0] != "void": fd.write(" if ret is None: raise libvirt.libvirtError('" + name + "() failed')\n") if ret[0] == "virDomainPtr": fd.write(" __tmp = virDomain(" + conn + ",_obj=ret)\n") fd.write(" return __tmp\n") else: fd.write(" return ret\n") fd.write("\n") # # Generate enum constants # for type,enum in lxc_enums.items(): fd.write("# %s\n" % type) items = enum.items() items.sort(lambda i1,i2: cmp(long(i1[1]),long(i2[1]))) for name,value in items: fd.write("%s = %s\n" % (name,value)) fd.write("\n") fd.close() quiet = 0 if buildStubs("libvirt") < 0: sys.exit(1) if buildStubs("libvirt-lxc") < 0: sys.exit(1) if buildStubs("libvirt-qemu") < 0: sys.exit(1) buildWrappers("libvirt") lxcBuildWrappers("libvirt-lxc") qemuBuildWrappers("libvirt-qemu") sys.exit(0) ='n2081' href='#n2081'>2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103 2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598
/* SPDX-License-Identifier: GPL-2.0+ */
/*******************************************************************************


  Copyright(c) 1999 - 2002 Intel Corporation. All rights reserved.
  Copyright 2011 Freescale Semiconductor, Inc.

  Contact Information:
  Linux NICS <linux.nics@intel.com>
  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497

*******************************************************************************/

/* e1000_hw.h
 * Structures, enums, and macros for the MAC
 */

#ifndef _E1000_HW_H_
#define _E1000_HW_H_

#include <linux/list.h>
#include <malloc.h>
#include <net.h>
/* Avoids a compile error since struct eth_device is not defined */
#ifndef CONFIG_DM_ETH
#include <netdev.h>
#endif
#include <asm/io.h>
#include <pci.h>

#ifdef CONFIG_E1000_SPI
#include <spi.h>
#endif

#define E1000_ERR(NIC, fmt, args...) \
	printf("e1000: %s: ERROR: " fmt, (NIC)->name ,##args)

#ifdef E1000_DEBUG
#define E1000_DBG(NIC, fmt, args...) \
	printf("e1000: %s: DEBUG: " fmt, (NIC)->name ,##args)
#define DEBUGOUT(fmt, args...)	printf(fmt ,##args)
#define DEBUGFUNC()		printf("%s\n", __func__);
#else
#define E1000_DBG(HW, args...)	do { } while (0)
#define DEBUGFUNC()		do { } while (0)
#define DEBUGOUT(fmt, args...)	do { } while (0)
#endif

/* I/O wrapper functions */
#define E1000_WRITE_REG(a, reg, value) \
	writel((value), ((a)->hw_addr + E1000_##reg))
#define E1000_READ_REG(a, reg) \
	readl((a)->hw_addr + E1000_##reg)
#define E1000_WRITE_REG_ARRAY(a, reg, offset, value) \
	writel((value), ((a)->hw_addr + E1000_##reg + ((offset) << 2)))
#define E1000_READ_REG_ARRAY(a, reg, offset) \
	readl((a)->hw_addr + E1000_##reg + ((offset) << 2))
#define E1000_WRITE_FLUSH(a) \
	do { E1000_READ_REG(a, STATUS); } while (0)

/* Forward declarations of structures used by the shared code */
struct e1000_hw;
struct e1000_hw_stats;

/* Internal E1000 helper functions */
struct e1000_hw *e1000_find_card(unsigned int cardnum);

#ifndef CONFIG_E1000_NO_NVM
int32_t e1000_acquire_eeprom(struct e1000_hw *hw);
void e1000_standby_eeprom(struct e1000_hw *hw);
void e1000_release_eeprom(struct e1000_hw *hw);
void e1000_raise_ee_clk(struct e1000_hw *hw, uint32_t *eecd);
void e1000_lower_ee_clk(struct e1000_hw *hw, uint32_t *eecd);
#endif

#ifdef CONFIG_E1000_SPI
int do_e1000_spi(struct cmd_tbl *cmdtp, struct e1000_hw *hw,
		 int argc, char *const argv[]);
#endif

/* Enumerated types specific to the e1000 hardware */
/* Media Access Controlers */
typedef enum {
	e1000_undefined = 0,
	e1000_82542_rev2_0,
	e1000_82542_rev2_1,
	e1000_82543,
	e1000_82544,
	e1000_82540,
	e1000_82545,
	e1000_82545_rev_3,
	e1000_82546,
	e1000_82546_rev_3,
	e1000_82541,
	e1000_82541_rev_2,
	e1000_82547,
	e1000_82547_rev_2,
	e1000_82571,
	e1000_82572,
	e1000_82573,
	e1000_82574,
	e1000_80003es2lan,
	e1000_ich8lan,
	e1000_igb,
	e1000_num_macs
} e1000_mac_type;

/* Media Types */
typedef enum {
	e1000_media_type_copper = 0,
	e1000_media_type_fiber = 1,
	e1000_media_type_internal_serdes = 2,
	e1000_num_media_types
} e1000_media_type;

typedef enum {
	e1000_eeprom_uninitialized = 0,
	e1000_eeprom_spi,
	e1000_eeprom_microwire,
	e1000_eeprom_flash,
	e1000_eeprom_ich8,
	e1000_eeprom_none, /* No NVM support */
	e1000_eeprom_invm,
	e1000_num_eeprom_types
} e1000_eeprom_type;

typedef enum {
	e1000_10_half = 0,
	e1000_10_full = 1,
	e1000_100_half = 2,
	e1000_100_full = 3
} e1000_speed_duplex_type;

/* Flow Control Settings */
typedef enum {
	e1000_fc_none = 0,
	e1000_fc_rx_pause = 1,
	e1000_fc_tx_pause = 2,
	e1000_fc_full = 3,
	e1000_fc_default = 0xFF
} e1000_fc_type;

/* PCI bus types */
typedef enum {
	e1000_bus_type_unknown = 0,
	e1000_bus_type_pci,
	e1000_bus_type_pcix,
	e1000_bus_type_pci_express,
	e1000_bus_type_reserved
} e1000_bus_type;

/* PCI bus speeds */
typedef enum {
	e1000_bus_speed_unknown = 0,
	e1000_bus_speed_33,
	e1000_bus_speed_66,
	e1000_bus_speed_100,
	e1000_bus_speed_133,
	e1000_bus_speed_reserved
} e1000_bus_speed;

/* PCI bus widths */
typedef enum {
	e1000_bus_width_unknown = 0,
	e1000_bus_width_32,
	e1000_bus_width_64
} e1000_bus_width;

/* PHY status info structure and supporting enums */
typedef enum {
	e1000_cable_length_50 = 0,
	e1000_cable_length_50_80,
	e1000_cable_length_80_110,
	e1000_cable_length_110_140,
	e1000_cable_length_140,
	e1000_cable_length_undefined = 0xFF
} e1000_cable_length;

typedef enum {
	e1000_10bt_ext_dist_enable_normal = 0,
	e1000_10bt_ext_dist_enable_lower,
	e1000_10bt_ext_dist_enable_undefined = 0xFF
} e1000_10bt_ext_dist_enable;

typedef enum {
	e1000_rev_polarity_normal = 0,
	e1000_rev_polarity_reversed,
	e1000_rev_polarity_undefined = 0xFF
} e1000_rev_polarity;

typedef enum {
	e1000_polarity_reversal_enabled = 0,
	e1000_polarity_reversal_disabled,
	e1000_polarity_reversal_undefined = 0xFF
} e1000_polarity_reversal;

typedef enum {
	e1000_auto_x_mode_manual_mdi = 0,
	e1000_auto_x_mode_manual_mdix,
	e1000_auto_x_mode_auto1,
	e1000_auto_x_mode_auto2,
	e1000_auto_x_mode_undefined = 0xFF
} e1000_auto_x_mode;

typedef enum {
	e1000_1000t_rx_status_not_ok = 0,
	e1000_1000t_rx_status_ok,
	e1000_1000t_rx_status_undefined = 0xFF
} e1000_1000t_rx_status;

typedef enum {
	e1000_phy_m88 = 0,
	e1000_phy_igp,
	e1000_phy_igp_2,
	e1000_phy_gg82563,
	e1000_phy_igp_3,
	e1000_phy_ife,
	e1000_phy_igb,
	e1000_phy_bm,
	e1000_phy_undefined = 0xFF
} e1000_phy_type;

struct e1000_phy_info {
	e1000_cable_length cable_length;
	e1000_10bt_ext_dist_enable extended_10bt_distance;
	e1000_rev_polarity cable_polarity;
	e1000_polarity_reversal polarity_correction;
	e1000_auto_x_mode mdix_mode;
	e1000_1000t_rx_status local_rx;
	e1000_1000t_rx_status remote_rx;
};

struct e1000_phy_stats {
	uint32_t idle_errors;
	uint32_t receive_errors;
};

/* Error Codes */
#define E1000_SUCCESS				0
#define E1000_ERR_EEPROM			1
#define E1000_ERR_PHY				2
#define E1000_ERR_CONFIG			3
#define E1000_ERR_PARAM				4
#define E1000_ERR_MAC_TYPE			5
#define E1000_ERR_PHY_TYPE			6
#define E1000_ERR_NOLINK			7
#define E1000_ERR_TIMEOUT			8
#define E1000_ERR_RESET				9
#define E1000_ERR_MASTER_REQUESTS_PENDING	10
#define E1000_ERR_HOST_INTERFACE_COMMAND	11
#define E1000_BLK_PHY_RESET			12
#define E1000_ERR_SWFW_SYNC 			13

/* PCI Device IDs */
#define E1000_DEV_ID_82542	    0x1000
#define E1000_DEV_ID_82543GC_FIBER  0x1001
#define E1000_DEV_ID_82543GC_COPPER 0x1004
#define E1000_DEV_ID_82544EI_COPPER 0x1008
#define E1000_DEV_ID_82544EI_FIBER  0x1009
#define E1000_DEV_ID_82544GC_COPPER 0x100C
#define E1000_DEV_ID_82544GC_LOM    0x100D
#define E1000_DEV_ID_82540EM	    0x100E
#define E1000_DEV_ID_82540EM_LOM         0x1015
#define E1000_DEV_ID_82540EP_LOM         0x1016
#define E1000_DEV_ID_82540EP             0x1017
#define E1000_DEV_ID_82540EP_LP          0x101E
#define E1000_DEV_ID_82545EM_COPPER      0x100F
#define E1000_DEV_ID_82545EM_FIBER       0x1011
#define E1000_DEV_ID_82545GM_COPPER      0x1026
#define E1000_DEV_ID_82545GM_FIBER       0x1027
#define E1000_DEV_ID_82545GM_SERDES      0x1028
#define E1000_DEV_ID_82546EB_COPPER      0x1010
#define E1000_DEV_ID_82546EB_FIBER       0x1012
#define E1000_DEV_ID_82546EB_QUAD_COPPER 0x101D
#define E1000_DEV_ID_82541EI             0x1013
#define E1000_DEV_ID_82541EI_MOBILE      0x1018
#define E1000_DEV_ID_82541ER_LOM         0x1014
#define E1000_DEV_ID_82541ER             0x1078
#define E1000_DEV_ID_82547GI             0x1075
#define E1000_DEV_ID_82541GI             0x1076
#define E1000_DEV_ID_82541GI_MOBILE      0x1077
#define E1000_DEV_ID_82541GI_LF          0x107C
#define E1000_DEV_ID_82546GB_COPPER      0x1079
#define E1000_DEV_ID_82546GB_FIBER       0x107A
#define E1000_DEV_ID_82546GB_SERDES      0x107B
#define E1000_DEV_ID_82546GB_PCIE        0x108A
#define E1000_DEV_ID_82546GB_QUAD_COPPER 0x1099
#define E1000_DEV_ID_82547EI             0x1019
#define E1000_DEV_ID_82547EI_MOBILE      0x101A
#define E1000_DEV_ID_82571EB_COPPER      0x105E
#define E1000_DEV_ID_82571EB_FIBER       0x105F
#define E1000_DEV_ID_82571EB_SERDES      0x1060
#define E1000_DEV_ID_82571EB_QUAD_COPPER 0x10A4
#define E1000_DEV_ID_82571PT_QUAD_COPPER 0x10D5
#define E1000_DEV_ID_82571EB_QUAD_FIBER  0x10A5
#define E1000_DEV_ID_82571EB_QUAD_COPPER_LOWPROFILE  0x10BC
#define E1000_DEV_ID_82571EB_SERDES_DUAL 0x10D9
#define E1000_DEV_ID_82571EB_SERDES_QUAD 0x10DA
#define E1000_DEV_ID_82572EI_COPPER      0x107D
#define E1000_DEV_ID_82572EI_FIBER       0x107E
#define E1000_DEV_ID_82572EI_SERDES      0x107F
#define E1000_DEV_ID_82572EI             0x10B9
#define E1000_DEV_ID_82573E              0x108B
#define E1000_DEV_ID_82573E_IAMT         0x108C
#define E1000_DEV_ID_82573L              0x109A
#define E1000_DEV_ID_82574L              0x10D3
#define E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3 0x10B5
#define E1000_DEV_ID_80003ES2LAN_COPPER_DPT     0x1096
#define E1000_DEV_ID_80003ES2LAN_SERDES_DPT     0x1098
#define E1000_DEV_ID_80003ES2LAN_COPPER_SPT     0x10BA
#define E1000_DEV_ID_80003ES2LAN_SERDES_SPT     0x10BB

#define E1000_DEV_ID_ICH8_IGP_M_AMT      0x1049
#define E1000_DEV_ID_ICH8_IGP_AMT        0x104A
#define E1000_DEV_ID_ICH8_IGP_C          0x104B
#define E1000_DEV_ID_ICH8_IFE            0x104C
#define E1000_DEV_ID_ICH8_IFE_GT         0x10C4
#define E1000_DEV_ID_ICH8_IFE_G          0x10C5
#define E1000_DEV_ID_ICH8_IGP_M          0x104D

#define IGP03E1000_E_PHY_ID  0x02A80390
#define IFE_E_PHY_ID         0x02A80330 /* 10/100 PHY */
#define IFE_PLUS_E_PHY_ID    0x02A80320
#define IFE_C_E_PHY_ID       0x02A80310

#define IFE_PHY_EXTENDED_STATUS_CONTROL   0x10  /* 100BaseTx Extended Status,
						   Control and Address */
#define IFE_PHY_SPECIAL_CONTROL           0x11  /* 100BaseTx PHY special
						   control register */
#define IFE_PHY_RCV_FALSE_CARRIER         0x13  /* 100BaseTx Receive false
						   Carrier Counter */
#define IFE_PHY_RCV_DISCONNECT            0x14  /* 100BaseTx Receive Disconnet
						   Counter */
#define IFE_PHY_RCV_ERROT_FRAME           0x15  /* 100BaseTx Receive Error
						   Frame Counter */
#define IFE_PHY_RCV_SYMBOL_ERR            0x16  /* Receive Symbol Error
						   Counter */
#define IFE_PHY_PREM_EOF_ERR              0x17  /* 100BaseTx Receive
						   Premature End Of Frame
						   Error Counter */
#define IFE_PHY_RCV_EOF_ERR               0x18  /* 10BaseT Receive End Of
						   Frame Error Counter */
#define IFE_PHY_TX_JABBER_DETECT          0x19  /* 10BaseT Transmit Jabber
						   Detect Counter */
#define IFE_PHY_EQUALIZER                 0x1A  /* PHY Equalizer Control and
						   Status */
#define IFE_PHY_SPECIAL_CONTROL_LED       0x1B  /* PHY special control and
						   LED configuration */
#define IFE_PHY_MDIX_CONTROL              0x1C  /* MDI/MDI-X Control register */
#define IFE_PHY_HWI_CONTROL               0x1D  /* Hardware Integrity Control
						   (HWI) */

#define IFE_PESC_REDUCED_POWER_DOWN_DISABLE  0x2000  /* Defaut 1 = Disable auto
							reduced power down */
#define IFE_PESC_100BTX_POWER_DOWN           0x0400  /* Indicates the power
							state of 100BASE-TX */
#define IFE_PESC_10BTX_POWER_DOWN            0x0200  /* Indicates the power
							state of 10BASE-T */
#define IFE_PESC_POLARITY_REVERSED           0x0100  /* Indicates 10BASE-T
							polarity */
#define IFE_PESC_PHY_ADDR_MASK               0x007C  /* Bit 6:2 for sampled PHY
							address */
#define IFE_PESC_SPEED                       0x0002  /* Auto-negotiation speed
						result 1=100Mbs, 0=10Mbs */
#define IFE_PESC_DUPLEX                      0x0001  /* Auto-negotiation
						duplex result 1=Full, 0=Half */
#define IFE_PESC_POLARITY_REVERSED_SHIFT     8

#define IFE_PSC_DISABLE_DYNAMIC_POWER_DOWN   0x0100  /* 1 = Dyanmic Power Down
							disabled */
#define IFE_PSC_FORCE_POLARITY               0x0020  /* 1=Reversed Polarity,
							0=Normal */
#define IFE_PSC_AUTO_POLARITY_DISABLE        0x0010  /* 1=Auto Polarity
							Disabled, 0=Enabled */
#define IFE_PSC_JABBER_FUNC_DISABLE          0x0001  /* 1=Jabber Disabled,
						0=Normal Jabber Operation */
#define IFE_PSC_FORCE_POLARITY_SHIFT         5
#define IFE_PSC_AUTO_POLARITY_DISABLE_SHIFT  4

#define IFE_PMC_AUTO_MDIX                    0x0080  /* 1=enable MDI/MDI-X
						feature, default 0=disabled */
#define IFE_PMC_FORCE_MDIX                   0x0040  /* 1=force MDIX-X,
							0=force MDI */
#define IFE_PMC_MDIX_STATUS                  0x0020  /* 1=MDI-X, 0=MDI */
#define IFE_PMC_AUTO_MDIX_COMPLETE           0x0010  /* Resolution algorithm
							is completed */
#define IFE_PMC_MDIX_MODE_SHIFT              6
#define IFE_PHC_MDIX_RESET_ALL_MASK          0x0000  /* Disable auto MDI-X */

#define IFE_PHC_HWI_ENABLE                   0x8000  /* Enable the HWI
							feature */
#define IFE_PHC_ABILITY_CHECK                0x4000  /* 1= Test Passed,
							0=failed */
#define IFE_PHC_TEST_EXEC                    0x2000  /* PHY launch test pulses
							on the wire */
#define IFE_PHC_HIGHZ                        0x0200  /* 1 = Open Circuit */
#define IFE_PHC_LOWZ                         0x0400  /* 1 = Short Circuit */
#define IFE_PHC_LOW_HIGH_Z_MASK              0x0600  /* Mask for indication
						type of problem on the line */
#define IFE_PHC_DISTANCE_MASK                0x01FF  /* Mask for distance to
				the cable problem, in 80cm granularity */
#define IFE_PHC_RESET_ALL_MASK               0x0000  /* Disable HWI */
#define IFE_PSCL_PROBE_MODE                  0x0020  /* LED Probe mode */
#define IFE_PSCL_PROBE_LEDS_OFF              0x0006  /* Force LEDs 0 and 2
							off */
#define IFE_PSCL_PROBE_LEDS_ON               0x0007  /* Force LEDs 0 and 2 on */


#define NUM_DEV_IDS 16

#define NODE_ADDRESS_SIZE 6
#define ETH_LENGTH_OF_ADDRESS 6

/* MAC decode size is 128K - This is the size of BAR0 */
#define MAC_DECODE_SIZE (128 * 1024)

#define E1000_82542_2_0_REV_ID 2
#define E1000_82542_2_1_REV_ID 3
#define E1000_REVISION_0       0
#define E1000_REVISION_1       1
#define E1000_REVISION_2       2
#define E1000_REVISION_3       3

#define SPEED_10    10
#define SPEED_100   100
#define SPEED_1000  1000
#define HALF_DUPLEX 1
#define FULL_DUPLEX 2

/* The sizes (in bytes) of a ethernet packet */
#define ENET_HEADER_SIZE	     14
#define MAXIMUM_ETHERNET_FRAME_SIZE  1518	/* With FCS */
#define MINIMUM_ETHERNET_FRAME_SIZE  64	/* With FCS */
#define MAXIMUM_ETHERNET_PACKET_SIZE \
	(MAXIMUM_ETHERNET_FRAME_SIZE - ETH_FCS_LEN)
#define MINIMUM_ETHERNET_PACKET_SIZE \
	(MINIMUM_ETHERNET_FRAME_SIZE - ETH_FCS_LEN)
#define CRC_LENGTH		     ETH_FCS_LEN
#define MAX_JUMBO_FRAME_SIZE	     0x3F00

/* 802.1q VLAN Packet Sizes */
#define VLAN_TAG_SIZE			  4	/* 802.3ac tag (not DMAed) */

/* Ethertype field values */
#define ETHERNET_IEEE_VLAN_TYPE 0x8100	/* 802.3ac packet */
#define ETHERNET_IP_TYPE	0x0800	/* IP packets */
#define ETHERNET_ARP_TYPE	0x0806	/* Address Resolution Protocol (ARP) */

/* Packet Header defines */
#define IP_PROTOCOL_TCP    6
#define IP_PROTOCOL_UDP    0x11

/* This defines the bits that are set in the Interrupt Mask
 * Set/Read Register.  Each bit is documented below:
 *   o RXDMT0 = Receive Descriptor Minimum Threshold hit (ring 0)
 *   o RXSEQ  = Receive Sequence Error
 */
#define POLL_IMS_ENABLE_MASK ( \
    E1000_IMS_RXDMT0 |	       \
    E1000_IMS_RXSEQ)

/* This defines the bits that are set in the Interrupt Mask
 * Set/Read Register.  Each bit is documented below:
 *   o RXT0   = Receiver Timer Interrupt (ring 0)
 *   o TXDW   = Transmit Descriptor Written Back
 *   o RXDMT0 = Receive Descriptor Minimum Threshold hit (ring 0)
 *   o RXSEQ  = Receive Sequence Error
 *   o LSC    = Link Status Change
 */
#define IMS_ENABLE_MASK ( \
    E1000_IMS_RXT0   |	  \
    E1000_IMS_TXDW   |	  \
    E1000_IMS_RXDMT0 |	  \
    E1000_IMS_RXSEQ  |	  \
    E1000_IMS_LSC)

/* The number of high/low register pairs in the RAR. The RAR (Receive Address
 * Registers) holds the directed and multicast addresses that we monitor. We
 * reserve one of these spots for our directed address, allowing us room for
 * E1000_RAR_ENTRIES - 1 multicast addresses.
 */
#define E1000_RAR_ENTRIES 16

#define MIN_NUMBER_OF_DESCRIPTORS 8
#define MAX_NUMBER_OF_DESCRIPTORS 0xFFF8

/* Receive Descriptor */
struct e1000_rx_desc {
	uint64_t buffer_addr;	/* Address of the descriptor's data buffer */
	uint16_t length;	/* Length of data DMAed into data buffer */
	uint16_t csum;		/* Packet checksum */
	uint8_t status;		/* Descriptor status */
	uint8_t errors;		/* Descriptor Errors */
	uint16_t special;
};

/* Receive Decriptor bit definitions */
#define E1000_RXD_STAT_DD	0x01	/* Descriptor Done */
#define E1000_RXD_STAT_EOP	0x02	/* End of Packet */
#define E1000_RXD_STAT_IXSM	0x04	/* Ignore checksum */
#define E1000_RXD_STAT_VP	0x08	/* IEEE VLAN Packet */
#define E1000_RXD_STAT_TCPCS	0x20	/* TCP xsum calculated */
#define E1000_RXD_STAT_IPCS	0x40	/* IP xsum calculated */
#define E1000_RXD_STAT_PIF	0x80	/* passed in-exact filter */
#define E1000_RXD_ERR_CE	0x01	/* CRC Error */
#define E1000_RXD_ERR_SE	0x02	/* Symbol Error */
#define E1000_RXD_ERR_SEQ	0x04	/* Sequence Error */
#define E1000_RXD_ERR_CXE	0x10	/* Carrier Extension Error */
#define E1000_RXD_ERR_TCPE	0x20	/* TCP/UDP Checksum Error */
#define E1000_RXD_ERR_IPE	0x40	/* IP Checksum Error */
#define E1000_RXD_ERR_RXE	0x80	/* Rx Data Error */
#define E1000_RXD_SPC_VLAN_MASK 0x0FFF	/* VLAN ID is in lower 12 bits */
#define E1000_RXD_SPC_PRI_MASK	0xE000	/* Priority is in upper 3 bits */
#define E1000_RXD_SPC_PRI_SHIFT 0x000D	/* Priority is in upper 3 of 16 */
#define E1000_RXD_SPC_CFI_MASK	0x1000	/* CFI is bit 12 */
#define E1000_RXD_SPC_CFI_SHIFT 0x000C	/* CFI is bit 12 */

/* mask to determine if packets should be dropped due to frame errors */
#define E1000_RXD_ERR_FRAME_ERR_MASK ( \
    E1000_RXD_ERR_CE  |		       \
    E1000_RXD_ERR_SE  |		       \
    E1000_RXD_ERR_SEQ |		       \
    E1000_RXD_ERR_CXE |		       \
    E1000_RXD_ERR_RXE)

/* Transmit Descriptor */
struct e1000_tx_desc {
	uint64_t buffer_addr;	/* Address of the descriptor's data buffer */
	union {
		uint32_t data;
		struct {
			uint16_t length;	/* Data buffer length */
			uint8_t cso;	/* Checksum offset */
			uint8_t cmd;	/* Descriptor control */
		} flags;
	} lower;
	union {
		uint32_t data;
		struct {
			uint8_t status;	/* Descriptor status */
			uint8_t css;	/* Checksum start */
			uint16_t special;
		} fields;
	} upper;
};

/* Transmit Descriptor bit definitions */
#define E1000_TXD_DTYP_D     0x00100000	/* Data Descriptor */
#define E1000_TXD_DTYP_C     0x00000000	/* Context Descriptor */
#define E1000_TXD_POPTS_IXSM 0x01	/* Insert IP checksum */
#define E1000_TXD_POPTS_TXSM 0x02	/* Insert TCP/UDP checksum */
#define E1000_TXD_CMD_EOP    0x01000000	/* End of Packet */
#define E1000_TXD_CMD_IFCS   0x02000000	/* Insert FCS (Ethernet CRC) */
#define E1000_TXD_CMD_IC     0x04000000	/* Insert Checksum */
#define E1000_TXD_CMD_RS     0x08000000	/* Report Status */
#define E1000_TXD_CMD_RPS    0x10000000	/* Report Packet Sent */
#define E1000_TXD_CMD_DEXT   0x20000000	/* Descriptor extension (0 = legacy) */
#define E1000_TXD_CMD_VLE    0x40000000	/* Add VLAN tag */
#define E1000_TXD_CMD_IDE    0x80000000	/* Enable Tidv register */
#define E1000_TXD_STAT_DD    0x00000001	/* Descriptor Done */
#define E1000_TXD_STAT_EC    0x00000002	/* Excess Collisions */
#define E1000_TXD_STAT_LC    0x00000004	/* Late Collisions */
#define E1000_TXD_STAT_TU    0x00000008	/* Transmit underrun */
#define E1000_TXD_CMD_TCP    0x01000000	/* TCP packet */
#define E1000_TXD_CMD_IP     0x02000000	/* IP packet */
#define E1000_TXD_CMD_TSE    0x04000000	/* TCP Seg enable */
#define E1000_TXD_STAT_TC    0x00000004	/* Tx Underrun */

/* Offload Context Descriptor */
struct e1000_context_desc {
	union {
		uint32_t ip_config;
		struct {
			uint8_t ipcss;	/* IP checksum start */
			uint8_t ipcso;	/* IP checksum offset */
			uint16_t ipcse;	/* IP checksum end */
		} ip_fields;
	} lower_setup;
	union {
		uint32_t tcp_config;
		struct {
			uint8_t tucss;	/* TCP checksum start */
			uint8_t tucso;	/* TCP checksum offset */
			uint16_t tucse;	/* TCP checksum end */
		} tcp_fields;
	} upper_setup;
	uint32_t cmd_and_length;	/* */
	union {
		uint32_t data;
		struct {
			uint8_t status;	/* Descriptor status */
			uint8_t hdr_len;	/* Header length */
			uint16_t mss;	/* Maximum segment size */
		} fields;
	} tcp_seg_setup;
};

/* Offload data descriptor */
struct e1000_data_desc {
	uint64_t buffer_addr;	/* Address of the descriptor's buffer address */
	union {
		uint32_t data;
		struct {
			uint16_t length;	/* Data buffer length */
			uint8_t typ_len_ext;	/* */
			uint8_t cmd;	/* */
		} flags;
	} lower;
	union {
		uint32_t data;
		struct {
			uint8_t status;	/* Descriptor status */
			uint8_t popts;	/* Packet Options */
			uint16_t special;	/* */
		} fields;
	} upper;
};

/* Filters */
#define E1000_NUM_UNICAST	   16	/* Unicast filter entries */