libvirt.org/go/libvirtxml@v1.10003.0/node_device.go (about)

     1  /*
     2   * This file is part of the libvirt-go-xml-module project
     3   *
     4   * Permission is hereby granted, free of charge, to any person obtaining a copy
     5   * of this software and associated documentation files (the "Software"), to deal
     6   * in the Software without restriction, including without limitation the rights
     7   * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     8   * copies of the Software, and to permit persons to whom the Software is
     9   * furnished to do so, subject to the following conditions:
    10   *
    11   * The above copyright notice and this permission notice shall be included in
    12   * all copies or substantial portions of the Software.
    13   *
    14   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    15   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    16   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    17   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    18   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    19   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    20   * THE SOFTWARE.
    21   *
    22   * Copyright (C) 2017 Red Hat, Inc.
    23   *
    24   */
    25  
    26  package libvirtxml
    27  
    28  import (
    29  	"encoding/xml"
    30  	"fmt"
    31  	"io"
    32  	"strconv"
    33  	"strings"
    34  )
    35  
    36  type NodeDevice struct {
    37  	XMLName    xml.Name             `xml:"device"`
    38  	Name       string               `xml:"name"`
    39  	Path       string               `xml:"path,omitempty"`
    40  	DevNodes   []NodeDeviceDevNode  `xml:"devnode"`
    41  	Parent     string               `xml:"parent,omitempty"`
    42  	Driver     *NodeDeviceDriver    `xml:"driver"`
    43  	Capability NodeDeviceCapability `xml:"capability"`
    44  }
    45  
    46  type NodeDeviceDevNode struct {
    47  	Type string `xml:"type,attr,omitempty"`
    48  	Path string `xml:",chardata"`
    49  }
    50  
    51  type NodeDeviceDriver struct {
    52  	Name string `xml:"name"`
    53  }
    54  
    55  type NodeDeviceCapability struct {
    56  	System     *NodeDeviceSystemCapability
    57  	PCI        *NodeDevicePCICapability
    58  	USB        *NodeDeviceUSBCapability
    59  	USBDevice  *NodeDeviceUSBDeviceCapability
    60  	Net        *NodeDeviceNetCapability
    61  	SCSIHost   *NodeDeviceSCSIHostCapability
    62  	SCSITarget *NodeDeviceSCSITargetCapability
    63  	SCSI       *NodeDeviceSCSICapability
    64  	Storage    *NodeDeviceStorageCapability
    65  	DRM        *NodeDeviceDRMCapability
    66  	CCW        *NodeDeviceCCWCapability
    67  	MDev       *NodeDeviceMDevCapability
    68  	CSS        *NodeDeviceCSSCapability
    69  	APQueue    *NodeDeviceAPQueueCapability
    70  	APCard     *NodeDeviceAPCardCapability
    71  	APMatrix   *NodeDeviceAPMatrixCapability
    72  }
    73  
    74  type NodeDeviceIDName struct {
    75  	ID   string `xml:"id,attr"`
    76  	Name string `xml:",chardata"`
    77  }
    78  
    79  type NodeDevicePCIExpress struct {
    80  	Links []NodeDevicePCIExpressLink `xml:"link"`
    81  }
    82  
    83  type NodeDevicePCIExpressLink struct {
    84  	Validity string  `xml:"validity,attr,omitempty"`
    85  	Speed    float64 `xml:"speed,attr,omitempty"`
    86  	Port     *uint   `xml:"port,attr"`
    87  	Width    *uint   `xml:"width,attr"`
    88  }
    89  
    90  type NodeDeviceIOMMUGroup struct {
    91  	Number  int                    `xml:"number,attr"`
    92  	Address []NodeDevicePCIAddress `xml:"address"`
    93  }
    94  
    95  type NodeDeviceNUMA struct {
    96  	Node int `xml:"node,attr"`
    97  }
    98  
    99  type NodeDevicePCICapability struct {
   100  	Class        string                       `xml:"class,omitempty"`
   101  	Domain       *uint                        `xml:"domain"`
   102  	Bus          *uint                        `xml:"bus"`
   103  	Slot         *uint                        `xml:"slot"`
   104  	Function     *uint                        `xml:"function"`
   105  	Product      NodeDeviceIDName             `xml:"product,omitempty"`
   106  	Vendor       NodeDeviceIDName             `xml:"vendor,omitempty"`
   107  	IOMMUGroup   *NodeDeviceIOMMUGroup        `xml:"iommuGroup"`
   108  	NUMA         *NodeDeviceNUMA              `xml:"numa"`
   109  	PCIExpress   *NodeDevicePCIExpress        `xml:"pci-express"`
   110  	Capabilities []NodeDevicePCISubCapability `xml:"capability"`
   111  }
   112  
   113  type NodeDevicePCIAddress struct {
   114  	Domain   *uint `xml:"domain,attr"`
   115  	Bus      *uint `xml:"bus,attr"`
   116  	Slot     *uint `xml:"slot,attr"`
   117  	Function *uint `xml:"function,attr"`
   118  }
   119  
   120  type NodeDevicePCISubCapability struct {
   121  	VirtFunctions *NodeDevicePCIVirtFunctionsCapability
   122  	PhysFunction  *NodeDevicePCIPhysFunctionCapability
   123  	MDevTypes     *NodeDevicePCIMDevTypesCapability
   124  	Bridge        *NodeDevicePCIBridgeCapability
   125  	VPD           *NodeDevicePCIVPDCapability
   126  }
   127  
   128  type NodeDevicePCIVirtFunctionsCapability struct {
   129  	Address  []NodeDevicePCIAddress `xml:"address,omitempty"`
   130  	MaxCount int                    `xml:"maxCount,attr,omitempty"`
   131  }
   132  
   133  type NodeDevicePCIPhysFunctionCapability struct {
   134  	Address NodeDevicePCIAddress `xml:"address,omitempty"`
   135  }
   136  
   137  type NodeDevicePCIMDevTypesCapability struct {
   138  	Types []NodeDeviceMDevType `xml:"type"`
   139  }
   140  
   141  type NodeDeviceMDevType struct {
   142  	ID                 string `xml:"id,attr"`
   143  	Name               string `xml:"name"`
   144  	DeviceAPI          string `xml:"deviceAPI"`
   145  	AvailableInstances uint   `xml:"availableInstances"`
   146  }
   147  
   148  type NodeDevicePCIBridgeCapability struct {
   149  }
   150  
   151  type NodeDevicePCIVPDCapability struct {
   152  	Name      string                    `xml:"name,omitempty"`
   153  	ReadOnly  *NodeDevicePCIVPDFieldsRO `xml:"-"`
   154  	ReadWrite *NodeDevicePCIVPDFieldsRW `xml:"-"`
   155  }
   156  
   157  type NodeDevicePCIVPDFieldsRO struct {
   158  	ChangeLevel   string                        `xml:"change_level,omitempty"`
   159  	ManufactureID string                        `xml:"manufacture_id,omitempty"`
   160  	PartNumber    string                        `xml:"part_number,omitempty"`
   161  	SerialNumber  string                        `xml:"serial_number,omitempty"`
   162  	VendorFields  []NodeDevicePCIVPDCustomField `xml:"vendor_field"`
   163  }
   164  
   165  type NodeDevicePCIVPDFieldsRW struct {
   166  	AssetTag     string                        `xml:"asset_tag,omitempty"`
   167  	VendorFields []NodeDevicePCIVPDCustomField `xml:"vendor_field"`
   168  	SystemFields []NodeDevicePCIVPDCustomField `xml:"system_field"`
   169  }
   170  
   171  type NodeDevicePCIVPDCustomField struct {
   172  	Index string `xml:"index,attr"`
   173  	Value string `xml:",chardata"`
   174  }
   175  
   176  type NodeDeviceSystemHardware struct {
   177  	Vendor  string `xml:"vendor"`
   178  	Version string `xml:"version"`
   179  	Serial  string `xml:"serial"`
   180  	UUID    string `xml:"uuid"`
   181  }
   182  
   183  type NodeDeviceSystemFirmware struct {
   184  	Vendor      string `xml:"vendor"`
   185  	Version     string `xml:"version"`
   186  	ReleaseData string `xml:"release_date"`
   187  }
   188  
   189  type NodeDeviceSystemCapability struct {
   190  	Product  string                    `xml:"product,omitempty"`
   191  	Hardware *NodeDeviceSystemHardware `xml:"hardware"`
   192  	Firmware *NodeDeviceSystemFirmware `xml:"firmware"`
   193  }
   194  
   195  type NodeDeviceUSBDeviceCapability struct {
   196  	Bus     int              `xml:"bus"`
   197  	Device  int              `xml:"device"`
   198  	Product NodeDeviceIDName `xml:"product,omitempty"`
   199  	Vendor  NodeDeviceIDName `xml:"vendor,omitempty"`
   200  }
   201  
   202  type NodeDeviceUSBCapability struct {
   203  	Number      int    `xml:"number"`
   204  	Class       int    `xml:"class"`
   205  	Subclass    int    `xml:"subclass"`
   206  	Protocol    int    `xml:"protocol"`
   207  	Description string `xml:"description,omitempty"`
   208  }
   209  
   210  type NodeDeviceNetOffloadFeatures struct {
   211  	Name string `xml:"name,attr"`
   212  }
   213  
   214  type NodeDeviceNetLink struct {
   215  	State string `xml:"state,attr"`
   216  	Speed string `xml:"speed,attr,omitempty"`
   217  }
   218  
   219  type NodeDeviceNetSubCapability struct {
   220  	Wireless80211 *NodeDeviceNet80211Capability
   221  	Ethernet80203 *NodeDeviceNet80203Capability
   222  }
   223  
   224  type NodeDeviceNet80211Capability struct {
   225  }
   226  
   227  type NodeDeviceNet80203Capability struct {
   228  }
   229  
   230  type NodeDeviceNetCapability struct {
   231  	Interface  string                         `xml:"interface"`
   232  	Address    string                         `xml:"address"`
   233  	Link       *NodeDeviceNetLink             `xml:"link"`
   234  	Features   []NodeDeviceNetOffloadFeatures `xml:"feature,omitempty"`
   235  	Capability []NodeDeviceNetSubCapability   `xml:"capability"`
   236  }
   237  
   238  type NodeDeviceSCSIVPortOpsCapability struct {
   239  	VPorts    int `xml:"vports"`
   240  	MaxVPorts int `xml:"max_vports"`
   241  }
   242  
   243  type NodeDeviceSCSIFCHostCapability struct {
   244  	WWNN      string `xml:"wwnn,omitempty"`
   245  	WWPN      string `xml:"wwpn,omitempty"`
   246  	FabricWWN string `xml:"fabric_wwn,omitempty"`
   247  }
   248  
   249  type NodeDeviceSCSIHostSubCapability struct {
   250  	VPortOps *NodeDeviceSCSIVPortOpsCapability
   251  	FCHost   *NodeDeviceSCSIFCHostCapability
   252  }
   253  
   254  type NodeDeviceSCSIHostCapability struct {
   255  	Host       uint                              `xml:"host"`
   256  	UniqueID   *uint                             `xml:"unique_id"`
   257  	Capability []NodeDeviceSCSIHostSubCapability `xml:"capability"`
   258  }
   259  
   260  type NodeDeviceSCSITargetCapability struct {
   261  	Target     string                              `xml:"target"`
   262  	Capability []NodeDeviceSCSITargetSubCapability `xml:"capability"`
   263  }
   264  
   265  type NodeDeviceSCSITargetSubCapability struct {
   266  	FCRemotePort *NodeDeviceSCSIFCRemotePortCapability
   267  }
   268  
   269  type NodeDeviceSCSIFCRemotePortCapability struct {
   270  	RPort string `xml:"rport"`
   271  	WWPN  string `xml:"wwpn"`
   272  }
   273  
   274  type NodeDeviceSCSICapability struct {
   275  	Host   int    `xml:"host"`
   276  	Bus    int    `xml:"bus"`
   277  	Target int    `xml:"target"`
   278  	Lun    int    `xml:"lun"`
   279  	Type   string `xml:"type"`
   280  }
   281  
   282  type NodeDeviceStorageSubCapability struct {
   283  	Removable *NodeDeviceStorageRemovableCapability
   284  }
   285  
   286  type NodeDeviceStorageRemovableCapability struct {
   287  	MediaAvailable   *uint  `xml:"media_available"`
   288  	MediaSize        *uint  `xml:"media_size"`
   289  	MediaLabel       string `xml:"media_label,omitempty"`
   290  	LogicalBlockSize *uint  `xml:"logical_block_size"`
   291  	NumBlocks        *uint  `xml:"num_blocks"`
   292  }
   293  
   294  type NodeDeviceStorageCapability struct {
   295  	Block            string                           `xml:"block,omitempty"`
   296  	Bus              string                           `xml:"bus,omitempty"`
   297  	DriverType       string                           `xml:"drive_type,omitempty"`
   298  	Model            string                           `xml:"model,omitempty"`
   299  	Vendor           string                           `xml:"vendor,omitempty"`
   300  	Serial           string                           `xml:"serial,omitempty"`
   301  	Size             *uint                            `xml:"size"`
   302  	LogicalBlockSize *uint                            `xml:"logical_block_size"`
   303  	NumBlocks        *uint                            `xml:"num_blocks"`
   304  	Capability       []NodeDeviceStorageSubCapability `xml:"capability"`
   305  }
   306  
   307  type NodeDeviceDRMCapability struct {
   308  	Type string `xml:"type"`
   309  }
   310  
   311  type NodeDeviceCCWCapability struct {
   312  	CSSID *uint `xml:"cssid"`
   313  	SSID  *uint `xml:"ssid"`
   314  	DevNo *uint `xml:"devno"`
   315  }
   316  
   317  type NodeDeviceMDevCapability struct {
   318  	Type       *NodeDeviceMDevCapabilityType   `xml:"type"`
   319  	IOMMUGroup *NodeDeviceIOMMUGroup           `xml:"iommuGroup"`
   320  	UUID       string                          `xml:"uuid,omitempty"`
   321  	ParentAddr string                          `xml:"parent_addr,omitempty"`
   322  	Attrs      []NodeDeviceMDevCapabilityAttrs `xml:"attr,omitempty"`
   323  }
   324  
   325  type NodeDeviceMDevCapabilityType struct {
   326  	ID string `xml:"id,attr"`
   327  }
   328  
   329  type NodeDeviceMDevCapabilityAttrs struct {
   330  	Name  string `xml:"name,attr"`
   331  	Value string `xml:"value,attr"`
   332  }
   333  
   334  type NodeDeviceCSSCapability struct {
   335  	CSSID          *uint                        `xml:"cssid"`
   336  	SSID           *uint                        `xml:"ssid"`
   337  	DevNo          *uint                        `xml:"devno"`
   338  	ChannelDevAddr *NodeDeviceCSSChannelDevAddr `xml:"channel_dev_addr"`
   339  	Capabilities   []NodeDeviceCSSSubCapability `xml:"capability"`
   340  }
   341  
   342  type NodeDeviceCSSChannelDevAddr struct {
   343  	CSSID *uint `xml:"cssid"`
   344  	SSID  *uint `xml:"ssid"`
   345  	DevNo *uint `xml:"devno"`
   346  }
   347  
   348  type NodeDeviceCSSSubCapability struct {
   349  	MDevTypes *NodeDeviceCSSMDevTypesCapability
   350  }
   351  
   352  type NodeDeviceCSSMDevTypesCapability struct {
   353  	Types []NodeDeviceMDevType `xml:"type"`
   354  }
   355  
   356  type NodeDeviceAPQueueCapability struct {
   357  	APAdapter string `xml:"ap-adapter"`
   358  	APDomain  string `xml:"ap-domain"`
   359  }
   360  
   361  type NodeDeviceAPCardCapability struct {
   362  	APAdapter string `xml:"ap-adapter"`
   363  }
   364  
   365  type NodeDeviceAPMatrixCapability struct {
   366  	Capabilities []NodeDeviceAPMatrixSubCapability `xml:"capability"`
   367  }
   368  
   369  type NodeDeviceAPMatrixSubCapability struct {
   370  	MDevTypes *NodeDeviceAPMatrixMDevTypesCapability
   371  }
   372  
   373  type NodeDeviceAPMatrixMDevTypesCapability struct {
   374  	Types []NodeDeviceMDevType `xml:"type"`
   375  }
   376  
   377  func (a *NodeDevicePCIAddress) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
   378  	marshalUintAttr(&start, "domain", a.Domain, "0x%04x")
   379  	marshalUintAttr(&start, "bus", a.Bus, "0x%02x")
   380  	marshalUintAttr(&start, "slot", a.Slot, "0x%02x")
   381  	marshalUintAttr(&start, "function", a.Function, "0x%x")
   382  	e.EncodeToken(start)
   383  	e.EncodeToken(start.End())
   384  	return nil
   385  }
   386  
   387  func (a *NodeDevicePCIAddress) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
   388  	for _, attr := range start.Attr {
   389  		if attr.Name.Local == "domain" {
   390  			if err := unmarshalUintAttr(attr.Value, &a.Domain, 0); err != nil {
   391  				return err
   392  			}
   393  		} else if attr.Name.Local == "bus" {
   394  			if err := unmarshalUintAttr(attr.Value, &a.Bus, 0); err != nil {
   395  				return err
   396  			}
   397  		} else if attr.Name.Local == "slot" {
   398  			if err := unmarshalUintAttr(attr.Value, &a.Slot, 0); err != nil {
   399  				return err
   400  			}
   401  		} else if attr.Name.Local == "function" {
   402  			if err := unmarshalUintAttr(attr.Value, &a.Function, 0); err != nil {
   403  				return err
   404  			}
   405  		}
   406  	}
   407  	d.Skip()
   408  	return nil
   409  }
   410  
   411  func (c *NodeDeviceCSSSubCapability) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
   412  	typ, ok := getAttr(start.Attr, "type")
   413  	if !ok {
   414  		return fmt.Errorf("Missing node device capability type")
   415  	}
   416  
   417  	switch typ {
   418  	case "mdev_types":
   419  		var mdevTypesCaps NodeDeviceCSSMDevTypesCapability
   420  		if err := d.DecodeElement(&mdevTypesCaps, &start); err != nil {
   421  			return err
   422  		}
   423  		c.MDevTypes = &mdevTypesCaps
   424  	}
   425  	d.Skip()
   426  	return nil
   427  }
   428  
   429  func (c *NodeDeviceCSSSubCapability) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
   430  	if c.MDevTypes != nil {
   431  		start.Attr = append(start.Attr, xml.Attr{
   432  			xml.Name{Local: "type"}, "mdev_types",
   433  		})
   434  		return e.EncodeElement(c.MDevTypes, start)
   435  	}
   436  	return nil
   437  }
   438  
   439  func (c *NodeDeviceCCWCapability) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
   440  	e.EncodeToken(start)
   441  	if c.CSSID != nil {
   442  		cssid := xml.StartElement{
   443  			Name: xml.Name{Local: "cssid"},
   444  		}
   445  		e.EncodeToken(cssid)
   446  		e.EncodeToken(xml.CharData(fmt.Sprintf("0x%x", *c.CSSID)))
   447  		e.EncodeToken(cssid.End())
   448  	}
   449  	if c.SSID != nil {
   450  		ssid := xml.StartElement{
   451  			Name: xml.Name{Local: "ssid"},
   452  		}
   453  		e.EncodeToken(ssid)
   454  		e.EncodeToken(xml.CharData(fmt.Sprintf("0x%x", *c.SSID)))
   455  		e.EncodeToken(ssid.End())
   456  	}
   457  	if c.DevNo != nil {
   458  		devno := xml.StartElement{
   459  			Name: xml.Name{Local: "devno"},
   460  		}
   461  		e.EncodeToken(devno)
   462  		e.EncodeToken(xml.CharData(fmt.Sprintf("0x%04x", *c.DevNo)))
   463  		e.EncodeToken(devno.End())
   464  	}
   465  	e.EncodeToken(start.End())
   466  	return nil
   467  }
   468  
   469  func (c *NodeDeviceCCWCapability) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
   470  	for {
   471  		tok, err := d.Token()
   472  		if err == io.EOF {
   473  			break
   474  		}
   475  		if err != nil {
   476  			return err
   477  		}
   478  
   479  		switch tok := tok.(type) {
   480  		case xml.StartElement:
   481  			cdata, err := d.Token()
   482  			if err != nil {
   483  				return err
   484  			}
   485  
   486  			if tok.Name.Local != "cssid" &&
   487  				tok.Name.Local != "ssid" &&
   488  				tok.Name.Local != "devno" {
   489  				continue
   490  			}
   491  
   492  			chardata, ok := cdata.(xml.CharData)
   493  			if !ok {
   494  				return fmt.Errorf("Expected text for CCW '%s'", tok.Name.Local)
   495  			}
   496  
   497  			valstr := strings.TrimPrefix(string(chardata), "0x")
   498  			val, err := strconv.ParseUint(valstr, 16, 64)
   499  			if err != nil {
   500  				return err
   501  			}
   502  
   503  			vali := uint(val)
   504  			if tok.Name.Local == "cssid" {
   505  				c.CSSID = &vali
   506  			} else if tok.Name.Local == "ssid" {
   507  				c.SSID = &vali
   508  			} else if tok.Name.Local == "devno" {
   509  				c.DevNo = &vali
   510  			}
   511  		}
   512  	}
   513  	return nil
   514  }
   515  
   516  func (c *NodeDeviceCSSCapability) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
   517  	e.EncodeToken(start)
   518  	if c.CSSID != nil {
   519  		cssid := xml.StartElement{
   520  			Name: xml.Name{Local: "cssid"},
   521  		}
   522  		e.EncodeToken(cssid)
   523  		e.EncodeToken(xml.CharData(fmt.Sprintf("0x%x", *c.CSSID)))
   524  		e.EncodeToken(cssid.End())
   525  	}
   526  	if c.SSID != nil {
   527  		ssid := xml.StartElement{
   528  			Name: xml.Name{Local: "ssid"},
   529  		}
   530  		e.EncodeToken(ssid)
   531  		e.EncodeToken(xml.CharData(fmt.Sprintf("0x%x", *c.SSID)))
   532  		e.EncodeToken(ssid.End())
   533  	}
   534  	if c.DevNo != nil {
   535  		devno := xml.StartElement{
   536  			Name: xml.Name{Local: "devno"},
   537  		}
   538  		e.EncodeToken(devno)
   539  		e.EncodeToken(xml.CharData(fmt.Sprintf("0x%04x", *c.DevNo)))
   540  		e.EncodeToken(devno.End())
   541  	}
   542  	if c.ChannelDevAddr != nil {
   543  		start := xml.StartElement{
   544  			Name: xml.Name{Local: "channel_dev_addr"},
   545  		}
   546  		e.EncodeElement(c.ChannelDevAddr, start)
   547  	}
   548  	if c.Capabilities != nil {
   549  		for _, subcap := range c.Capabilities {
   550  			start := xml.StartElement{
   551  				Name: xml.Name{Local: "capability"},
   552  			}
   553  			e.EncodeElement(&subcap, start)
   554  		}
   555  	}
   556  	e.EncodeToken(start.End())
   557  	return nil
   558  }
   559  
   560  func (c *NodeDeviceCSSCapability) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
   561  	for {
   562  		tok, err := d.Token()
   563  		if err == io.EOF {
   564  			break
   565  		}
   566  		if err != nil {
   567  			return err
   568  		}
   569  
   570  		switch tok := tok.(type) {
   571  		case xml.StartElement:
   572  			cdata, err := d.Token()
   573  			if err != nil {
   574  				return err
   575  			}
   576  
   577  			if tok.Name.Local == "capability" {
   578  				subcap := &NodeDeviceCSSSubCapability{}
   579  				err := d.DecodeElement(subcap, &tok)
   580  				if err != nil {
   581  					return err
   582  				}
   583  				c.Capabilities = append(c.Capabilities, *subcap)
   584  				continue
   585  			} else if tok.Name.Local == "channel_dev_addr" {
   586  				chandev := &NodeDeviceCSSChannelDevAddr{}
   587  				err := d.DecodeElement(chandev, &tok)
   588  				if err != nil {
   589  					return err
   590  				}
   591  				c.ChannelDevAddr = chandev
   592  				continue
   593  			}
   594  
   595  			if tok.Name.Local != "cssid" &&
   596  				tok.Name.Local != "ssid" &&
   597  				tok.Name.Local != "devno" {
   598  				continue
   599  			}
   600  
   601  			chardata, ok := cdata.(xml.CharData)
   602  			if !ok {
   603  				return fmt.Errorf("Expected text for CSS '%s'", tok.Name.Local)
   604  			}
   605  
   606  			valstr := strings.TrimPrefix(string(chardata), "0x")
   607  			val, err := strconv.ParseUint(valstr, 16, 64)
   608  			if err != nil {
   609  				return err
   610  			}
   611  
   612  			vali := uint(val)
   613  			if tok.Name.Local == "cssid" {
   614  				c.CSSID = &vali
   615  			} else if tok.Name.Local == "ssid" {
   616  				c.SSID = &vali
   617  			} else if tok.Name.Local == "devno" {
   618  				c.DevNo = &vali
   619  			}
   620  		}
   621  	}
   622  	return nil
   623  }
   624  
   625  func (c *NodeDeviceCSSChannelDevAddr) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
   626  	e.EncodeToken(start)
   627  	if c.CSSID != nil {
   628  		cssid := xml.StartElement{
   629  			Name: xml.Name{Local: "cssid"},
   630  		}
   631  		e.EncodeToken(cssid)
   632  		e.EncodeToken(xml.CharData(fmt.Sprintf("0x%x", *c.CSSID)))
   633  		e.EncodeToken(cssid.End())
   634  	}
   635  	if c.SSID != nil {
   636  		ssid := xml.StartElement{
   637  			Name: xml.Name{Local: "ssid"},
   638  		}
   639  		e.EncodeToken(ssid)
   640  		e.EncodeToken(xml.CharData(fmt.Sprintf("0x%x", *c.SSID)))
   641  		e.EncodeToken(ssid.End())
   642  	}
   643  	if c.DevNo != nil {
   644  		devno := xml.StartElement{
   645  			Name: xml.Name{Local: "devno"},
   646  		}
   647  		e.EncodeToken(devno)
   648  		e.EncodeToken(xml.CharData(fmt.Sprintf("0x%04x", *c.DevNo)))
   649  		e.EncodeToken(devno.End())
   650  	}
   651  	e.EncodeToken(start.End())
   652  	return nil
   653  }
   654  
   655  func (c *NodeDeviceCSSChannelDevAddr) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
   656  	for {
   657  		tok, err := d.Token()
   658  		if err == io.EOF {
   659  			break
   660  		}
   661  		if err != nil {
   662  			return err
   663  		}
   664  
   665  		switch tok := tok.(type) {
   666  		case xml.StartElement:
   667  			cdata, err := d.Token()
   668  			if err != nil {
   669  				return err
   670  			}
   671  
   672  			if tok.Name.Local != "cssid" &&
   673  				tok.Name.Local != "ssid" &&
   674  				tok.Name.Local != "devno" {
   675  				continue
   676  			}
   677  
   678  			chardata, ok := cdata.(xml.CharData)
   679  			if !ok {
   680  				return fmt.Errorf("Expected text for CSS '%s'", tok.Name.Local)
   681  			}
   682  
   683  			valstr := strings.TrimPrefix(string(chardata), "0x")
   684  			val, err := strconv.ParseUint(valstr, 16, 64)
   685  			if err != nil {
   686  				return err
   687  			}
   688  
   689  			vali := uint(val)
   690  			if tok.Name.Local == "cssid" {
   691  				c.CSSID = &vali
   692  			} else if tok.Name.Local == "ssid" {
   693  				c.SSID = &vali
   694  			} else if tok.Name.Local == "devno" {
   695  				c.DevNo = &vali
   696  			}
   697  		}
   698  	}
   699  	return nil
   700  }
   701  
   702  func (c *NodeDevicePCISubCapability) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
   703  	typ, ok := getAttr(start.Attr, "type")
   704  	if !ok {
   705  		return fmt.Errorf("Missing node device capability type")
   706  	}
   707  
   708  	switch typ {
   709  	case "virt_functions":
   710  		var virtFuncCaps NodeDevicePCIVirtFunctionsCapability
   711  		if err := d.DecodeElement(&virtFuncCaps, &start); err != nil {
   712  			return err
   713  		}
   714  		c.VirtFunctions = &virtFuncCaps
   715  	case "phys_function":
   716  		var physFuncCaps NodeDevicePCIPhysFunctionCapability
   717  		if err := d.DecodeElement(&physFuncCaps, &start); err != nil {
   718  			return err
   719  		}
   720  		c.PhysFunction = &physFuncCaps
   721  	case "mdev_types":
   722  		var mdevTypeCaps NodeDevicePCIMDevTypesCapability
   723  		if err := d.DecodeElement(&mdevTypeCaps, &start); err != nil {
   724  			return err
   725  		}
   726  		c.MDevTypes = &mdevTypeCaps
   727  	case "pci-bridge":
   728  		var bridgeCaps NodeDevicePCIBridgeCapability
   729  		if err := d.DecodeElement(&bridgeCaps, &start); err != nil {
   730  			return err
   731  		}
   732  		c.Bridge = &bridgeCaps
   733  	case "vpd":
   734  		var vpdCaps NodeDevicePCIVPDCapability
   735  		if err := d.DecodeElement(&vpdCaps, &start); err != nil {
   736  			return err
   737  		}
   738  		c.VPD = &vpdCaps
   739  	}
   740  	d.Skip()
   741  	return nil
   742  }
   743  
   744  func (c *NodeDevicePCISubCapability) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
   745  	if c.VirtFunctions != nil {
   746  		start.Attr = append(start.Attr, xml.Attr{
   747  			xml.Name{Local: "type"}, "virt_functions",
   748  		})
   749  		return e.EncodeElement(c.VirtFunctions, start)
   750  	} else if c.PhysFunction != nil {
   751  		start.Attr = append(start.Attr, xml.Attr{
   752  			xml.Name{Local: "type"}, "phys_function",
   753  		})
   754  		return e.EncodeElement(c.PhysFunction, start)
   755  	} else if c.MDevTypes != nil {
   756  		start.Attr = append(start.Attr, xml.Attr{
   757  			xml.Name{Local: "type"}, "mdev_types",
   758  		})
   759  		return e.EncodeElement(c.MDevTypes, start)
   760  	} else if c.Bridge != nil {
   761  		start.Attr = append(start.Attr, xml.Attr{
   762  			xml.Name{Local: "type"}, "pci-bridge",
   763  		})
   764  		return e.EncodeElement(c.Bridge, start)
   765  	} else if c.VPD != nil {
   766  		start.Attr = append(start.Attr, xml.Attr{
   767  			xml.Name{Local: "type"}, "vpd",
   768  		})
   769  		return e.EncodeElement(c.VPD, start)
   770  	}
   771  	return nil
   772  }
   773  
   774  func (c *NodeDeviceSCSITargetSubCapability) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
   775  	typ, ok := getAttr(start.Attr, "type")
   776  	if !ok {
   777  		return fmt.Errorf("Missing node device capability type")
   778  	}
   779  
   780  	switch typ {
   781  	case "fc_remote_port":
   782  		var fcCaps NodeDeviceSCSIFCRemotePortCapability
   783  		if err := d.DecodeElement(&fcCaps, &start); err != nil {
   784  			return err
   785  		}
   786  		c.FCRemotePort = &fcCaps
   787  	}
   788  	d.Skip()
   789  	return nil
   790  }
   791  
   792  func (c *NodeDeviceSCSITargetSubCapability) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
   793  	if c.FCRemotePort != nil {
   794  		start.Attr = append(start.Attr, xml.Attr{
   795  			xml.Name{Local: "type"}, "fc_remote_port",
   796  		})
   797  		return e.EncodeElement(c.FCRemotePort, start)
   798  	}
   799  	return nil
   800  }
   801  
   802  func (c *NodeDeviceSCSIHostSubCapability) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
   803  	typ, ok := getAttr(start.Attr, "type")
   804  	if !ok {
   805  		return fmt.Errorf("Missing node device capability type")
   806  	}
   807  
   808  	switch typ {
   809  	case "fc_host":
   810  		var fcCaps NodeDeviceSCSIFCHostCapability
   811  		if err := d.DecodeElement(&fcCaps, &start); err != nil {
   812  			return err
   813  		}
   814  		c.FCHost = &fcCaps
   815  	case "vport_ops":
   816  		var vportCaps NodeDeviceSCSIVPortOpsCapability
   817  		if err := d.DecodeElement(&vportCaps, &start); err != nil {
   818  			return err
   819  		}
   820  		c.VPortOps = &vportCaps
   821  	}
   822  	d.Skip()
   823  	return nil
   824  }
   825  
   826  func (c *NodeDeviceSCSIHostSubCapability) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
   827  	if c.FCHost != nil {
   828  		start.Attr = append(start.Attr, xml.Attr{
   829  			xml.Name{Local: "type"}, "fc_host",
   830  		})
   831  		return e.EncodeElement(c.FCHost, start)
   832  	} else if c.VPortOps != nil {
   833  		start.Attr = append(start.Attr, xml.Attr{
   834  			xml.Name{Local: "type"}, "vport_ops",
   835  		})
   836  		return e.EncodeElement(c.VPortOps, start)
   837  	}
   838  	return nil
   839  }
   840  
   841  func (c *NodeDeviceStorageSubCapability) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
   842  	typ, ok := getAttr(start.Attr, "type")
   843  	if !ok {
   844  		return fmt.Errorf("Missing node device capability type")
   845  	}
   846  
   847  	switch typ {
   848  	case "removable":
   849  		var removeCaps NodeDeviceStorageRemovableCapability
   850  		if err := d.DecodeElement(&removeCaps, &start); err != nil {
   851  			return err
   852  		}
   853  		c.Removable = &removeCaps
   854  	}
   855  	d.Skip()
   856  	return nil
   857  }
   858  
   859  func (c *NodeDeviceStorageSubCapability) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
   860  	if c.Removable != nil {
   861  		start.Attr = append(start.Attr, xml.Attr{
   862  			xml.Name{Local: "type"}, "removable",
   863  		})
   864  		return e.EncodeElement(c.Removable, start)
   865  	}
   866  	return nil
   867  }
   868  
   869  func (c *NodeDeviceNetSubCapability) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
   870  	typ, ok := getAttr(start.Attr, "type")
   871  	if !ok {
   872  		return fmt.Errorf("Missing node device capability type")
   873  	}
   874  
   875  	switch typ {
   876  	case "80211":
   877  		var wlanCaps NodeDeviceNet80211Capability
   878  		if err := d.DecodeElement(&wlanCaps, &start); err != nil {
   879  			return err
   880  		}
   881  		c.Wireless80211 = &wlanCaps
   882  	case "80203":
   883  		var ethCaps NodeDeviceNet80203Capability
   884  		if err := d.DecodeElement(&ethCaps, &start); err != nil {
   885  			return err
   886  		}
   887  		c.Ethernet80203 = &ethCaps
   888  	}
   889  	d.Skip()
   890  	return nil
   891  }
   892  
   893  func (c *NodeDeviceNetSubCapability) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
   894  	if c.Wireless80211 != nil {
   895  		start.Attr = append(start.Attr, xml.Attr{
   896  			xml.Name{Local: "type"}, "80211",
   897  		})
   898  		return e.EncodeElement(c.Wireless80211, start)
   899  	} else if c.Ethernet80203 != nil {
   900  		start.Attr = append(start.Attr, xml.Attr{
   901  			xml.Name{Local: "type"}, "80203",
   902  		})
   903  		return e.EncodeElement(c.Ethernet80203, start)
   904  	}
   905  	return nil
   906  }
   907  
   908  func (c *NodeDeviceAPMatrixSubCapability) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
   909  	typ, ok := getAttr(start.Attr, "type")
   910  	if !ok {
   911  		return fmt.Errorf("Missing node device capability type")
   912  	}
   913  
   914  	switch typ {
   915  	case "mdev_types":
   916  		var mdevTypeCaps NodeDeviceAPMatrixMDevTypesCapability
   917  		if err := d.DecodeElement(&mdevTypeCaps, &start); err != nil {
   918  			return err
   919  		}
   920  		c.MDevTypes = &mdevTypeCaps
   921  	}
   922  	d.Skip()
   923  	return nil
   924  }
   925  
   926  func (c *NodeDeviceAPMatrixSubCapability) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
   927  	if c.MDevTypes != nil {
   928  		start.Attr = append(start.Attr, xml.Attr{
   929  			xml.Name{Local: "type"}, "mdev_types",
   930  		})
   931  		return e.EncodeElement(c.MDevTypes, start)
   932  	}
   933  	return nil
   934  }
   935  
   936  type nodeDevicePCIVPDFields struct {
   937  	ReadOnly  *NodeDevicePCIVPDFieldsRO
   938  	ReadWrite *NodeDevicePCIVPDFieldsRW
   939  }
   940  
   941  type nodeDevicePCIVPDCapability struct {
   942  	Name   string                   `xml:"name,omitempty"`
   943  	Fields []nodeDevicePCIVPDFields `xml:"fields"`
   944  }
   945  
   946  func (c *nodeDevicePCIVPDFields) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
   947  	acc, ok := getAttr(start.Attr, "access")
   948  	if !ok {
   949  		return fmt.Errorf("Missing node device PCI VPD capability access")
   950  	}
   951  
   952  	switch acc {
   953  	case "readonly":
   954  		var ro NodeDevicePCIVPDFieldsRO
   955  		if err := d.DecodeElement(&ro, &start); err != nil {
   956  			return err
   957  		}
   958  		c.ReadOnly = &ro
   959  	case "readwrite":
   960  		var rw NodeDevicePCIVPDFieldsRW
   961  		if err := d.DecodeElement(&rw, &start); err != nil {
   962  			return err
   963  		}
   964  		c.ReadWrite = &rw
   965  	}
   966  	d.Skip()
   967  	return nil
   968  }
   969  
   970  func (c *NodeDevicePCIVPDCapability) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
   971  	var ccopy nodeDevicePCIVPDCapability
   972  	ccopy.Name = c.Name
   973  	if c.ReadOnly != nil {
   974  		ccopy.Fields = append(ccopy.Fields, nodeDevicePCIVPDFields{
   975  			ReadOnly: c.ReadOnly,
   976  		})
   977  	}
   978  	if c.ReadWrite != nil {
   979  		ccopy.Fields = append(ccopy.Fields, nodeDevicePCIVPDFields{
   980  			ReadWrite: c.ReadWrite,
   981  		})
   982  	}
   983  	e.EncodeElement(&ccopy, start)
   984  	return nil
   985  }
   986  
   987  func (c *NodeDevicePCIVPDCapability) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
   988  	var ccopy nodeDevicePCIVPDCapability
   989  	if err := d.DecodeElement(&ccopy, &start); err != nil {
   990  		return err
   991  	}
   992  	c.Name = ccopy.Name
   993  	for _, field := range ccopy.Fields {
   994  		if field.ReadOnly != nil {
   995  			c.ReadOnly = field.ReadOnly
   996  		} else if field.ReadWrite != nil {
   997  			c.ReadWrite = field.ReadWrite
   998  		}
   999  	}
  1000  	return nil
  1001  }
  1002  
  1003  func (c *nodeDevicePCIVPDFields) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
  1004  	if c.ReadOnly != nil {
  1005  		start.Attr = append(start.Attr, xml.Attr{
  1006  			xml.Name{Local: "access"}, "readonly",
  1007  		})
  1008  		return e.EncodeElement(c.ReadOnly, start)
  1009  	} else if c.ReadWrite != nil {
  1010  		start.Attr = append(start.Attr, xml.Attr{
  1011  			xml.Name{Local: "access"}, "readwrite",
  1012  		})
  1013  		return e.EncodeElement(c.ReadWrite, start)
  1014  	}
  1015  	return nil
  1016  }
  1017  
  1018  func (c *NodeDeviceCapability) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
  1019  	typ, ok := getAttr(start.Attr, "type")
  1020  	if !ok {
  1021  		return fmt.Errorf("Missing node device capability type")
  1022  	}
  1023  
  1024  	switch typ {
  1025  	case "pci":
  1026  		var pciCaps NodeDevicePCICapability
  1027  		if err := d.DecodeElement(&pciCaps, &start); err != nil {
  1028  			return err
  1029  		}
  1030  		c.PCI = &pciCaps
  1031  	case "system":
  1032  		var systemCaps NodeDeviceSystemCapability
  1033  		if err := d.DecodeElement(&systemCaps, &start); err != nil {
  1034  			return err
  1035  		}
  1036  		c.System = &systemCaps
  1037  	case "usb_device":
  1038  		var usbdevCaps NodeDeviceUSBDeviceCapability
  1039  		if err := d.DecodeElement(&usbdevCaps, &start); err != nil {
  1040  			return err
  1041  		}
  1042  		c.USBDevice = &usbdevCaps
  1043  	case "usb":
  1044  		var usbCaps NodeDeviceUSBCapability
  1045  		if err := d.DecodeElement(&usbCaps, &start); err != nil {
  1046  			return err
  1047  		}
  1048  		c.USB = &usbCaps
  1049  	case "net":
  1050  		var netCaps NodeDeviceNetCapability
  1051  		if err := d.DecodeElement(&netCaps, &start); err != nil {
  1052  			return err
  1053  		}
  1054  		c.Net = &netCaps
  1055  	case "scsi_host":
  1056  		var scsiHostCaps NodeDeviceSCSIHostCapability
  1057  		if err := d.DecodeElement(&scsiHostCaps, &start); err != nil {
  1058  			return err
  1059  		}
  1060  		c.SCSIHost = &scsiHostCaps
  1061  	case "scsi_target":
  1062  		var scsiTargetCaps NodeDeviceSCSITargetCapability
  1063  		if err := d.DecodeElement(&scsiTargetCaps, &start); err != nil {
  1064  			return err
  1065  		}
  1066  		c.SCSITarget = &scsiTargetCaps
  1067  	case "scsi":
  1068  		var scsiCaps NodeDeviceSCSICapability
  1069  		if err := d.DecodeElement(&scsiCaps, &start); err != nil {
  1070  			return err
  1071  		}
  1072  		c.SCSI = &scsiCaps
  1073  	case "storage":
  1074  		var storageCaps NodeDeviceStorageCapability
  1075  		if err := d.DecodeElement(&storageCaps, &start); err != nil {
  1076  			return err
  1077  		}
  1078  		c.Storage = &storageCaps
  1079  	case "drm":
  1080  		var drmCaps NodeDeviceDRMCapability
  1081  		if err := d.DecodeElement(&drmCaps, &start); err != nil {
  1082  			return err
  1083  		}
  1084  		c.DRM = &drmCaps
  1085  	case "ccw":
  1086  		var ccwCaps NodeDeviceCCWCapability
  1087  		if err := d.DecodeElement(&ccwCaps, &start); err != nil {
  1088  			return err
  1089  		}
  1090  		c.CCW = &ccwCaps
  1091  	case "mdev":
  1092  		var mdevCaps NodeDeviceMDevCapability
  1093  		if err := d.DecodeElement(&mdevCaps, &start); err != nil {
  1094  			return err
  1095  		}
  1096  		c.MDev = &mdevCaps
  1097  	case "css":
  1098  		var cssCaps NodeDeviceCSSCapability
  1099  		if err := d.DecodeElement(&cssCaps, &start); err != nil {
  1100  			return err
  1101  		}
  1102  		c.CSS = &cssCaps
  1103  	case "ap_queue":
  1104  		var apCaps NodeDeviceAPQueueCapability
  1105  		if err := d.DecodeElement(&apCaps, &start); err != nil {
  1106  			return err
  1107  		}
  1108  		c.APQueue = &apCaps
  1109  	case "ap_matrix":
  1110  		var apCaps NodeDeviceAPMatrixCapability
  1111  		if err := d.DecodeElement(&apCaps, &start); err != nil {
  1112  			return err
  1113  		}
  1114  		c.APMatrix = &apCaps
  1115  	case "ap_card":
  1116  		var apCaps NodeDeviceAPCardCapability
  1117  		if err := d.DecodeElement(&apCaps, &start); err != nil {
  1118  			return err
  1119  		}
  1120  		c.APCard = &apCaps
  1121  	}
  1122  	d.Skip()
  1123  	return nil
  1124  }
  1125  
  1126  func (c *NodeDeviceCapability) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
  1127  	if c.PCI != nil {
  1128  		start.Attr = append(start.Attr, xml.Attr{
  1129  			xml.Name{Local: "type"}, "pci",
  1130  		})
  1131  		return e.EncodeElement(c.PCI, start)
  1132  	} else if c.System != nil {
  1133  		start.Attr = append(start.Attr, xml.Attr{
  1134  			xml.Name{Local: "type"}, "system",
  1135  		})
  1136  		return e.EncodeElement(c.System, start)
  1137  	} else if c.USB != nil {
  1138  		start.Attr = append(start.Attr, xml.Attr{
  1139  			xml.Name{Local: "type"}, "usb",
  1140  		})
  1141  		return e.EncodeElement(c.USB, start)
  1142  	} else if c.USBDevice != nil {
  1143  		start.Attr = append(start.Attr, xml.Attr{
  1144  			xml.Name{Local: "type"}, "usb_device",
  1145  		})
  1146  		return e.EncodeElement(c.USBDevice, start)
  1147  	} else if c.Net != nil {
  1148  		start.Attr = append(start.Attr, xml.Attr{
  1149  			xml.Name{Local: "type"}, "net",
  1150  		})
  1151  		return e.EncodeElement(c.Net, start)
  1152  	} else if c.SCSI != nil {
  1153  		start.Attr = append(start.Attr, xml.Attr{
  1154  			xml.Name{Local: "type"}, "scsi",
  1155  		})
  1156  		return e.EncodeElement(c.SCSI, start)
  1157  	} else if c.SCSIHost != nil {
  1158  		start.Attr = append(start.Attr, xml.Attr{
  1159  			xml.Name{Local: "type"}, "scsi_host",
  1160  		})
  1161  		return e.EncodeElement(c.SCSIHost, start)
  1162  	} else if c.SCSITarget != nil {
  1163  		start.Attr = append(start.Attr, xml.Attr{
  1164  			xml.Name{Local: "type"}, "scsi_target",
  1165  		})
  1166  		return e.EncodeElement(c.SCSITarget, start)
  1167  	} else if c.Storage != nil {
  1168  		start.Attr = append(start.Attr, xml.Attr{
  1169  			xml.Name{Local: "type"}, "storage",
  1170  		})
  1171  		return e.EncodeElement(c.Storage, start)
  1172  	} else if c.DRM != nil {
  1173  		start.Attr = append(start.Attr, xml.Attr{
  1174  			xml.Name{Local: "type"}, "drm",
  1175  		})
  1176  		return e.EncodeElement(c.DRM, start)
  1177  	} else if c.CCW != nil {
  1178  		start.Attr = append(start.Attr, xml.Attr{
  1179  			xml.Name{Local: "type"}, "ccw",
  1180  		})
  1181  		return e.EncodeElement(c.CCW, start)
  1182  	} else if c.MDev != nil {
  1183  		start.Attr = append(start.Attr, xml.Attr{
  1184  			xml.Name{Local: "type"}, "mdev",
  1185  		})
  1186  		return e.EncodeElement(c.MDev, start)
  1187  	} else if c.CSS != nil {
  1188  		start.Attr = append(start.Attr, xml.Attr{
  1189  			xml.Name{Local: "type"}, "css",
  1190  		})
  1191  		return e.EncodeElement(c.CSS, start)
  1192  	} else if c.APQueue != nil {
  1193  		start.Attr = append(start.Attr, xml.Attr{
  1194  			xml.Name{Local: "type"}, "ap_queue",
  1195  		})
  1196  		return e.EncodeElement(c.APQueue, start)
  1197  	} else if c.APCard != nil {
  1198  		start.Attr = append(start.Attr, xml.Attr{
  1199  			xml.Name{Local: "type"}, "ap_card",
  1200  		})
  1201  		return e.EncodeElement(c.APCard, start)
  1202  	} else if c.APMatrix != nil {
  1203  		start.Attr = append(start.Attr, xml.Attr{
  1204  			xml.Name{Local: "type"}, "ap_matrix",
  1205  		})
  1206  		return e.EncodeElement(c.APMatrix, start)
  1207  	}
  1208  	return nil
  1209  }
  1210  
  1211  func (c *NodeDevice) Unmarshal(doc string) error {
  1212  	return xml.Unmarshal([]byte(doc), c)
  1213  }
  1214  
  1215  func (c *NodeDevice) Marshal() (string, error) {
  1216  	doc, err := xml.MarshalIndent(c, "", "  ")
  1217  	if err != nil {
  1218  		return "", err
  1219  	}
  1220  	return string(doc), nil
  1221  }