@@ -8,20 +8,24 @@ import (
88// Address Represents a PCI Address including
99// domain, bus, device, and function.
1010type Address struct {
11- // Number The 32-bit PCI hardware address.
12- // This contains the domain (16 bits), bus (8 bits),
11+ // Number The 32bit/48bit PCI hardware address.
12+ // This contains the domain (16/32 bits), bus (8 bits),
1313 // device (5 bits), and function (3 bits).
14- Number uint32
14+ Number uint64
1515}
1616
17- // Domain Get the domain as uint16
18- func (s * Address ) Domain () uint16 {
19- return uint16 (s .Number >> 16 )
17+ // Domain Get the domain as uint32
18+ func (s * Address ) Domain () uint32 {
19+ return uint32 (s .Number >> 16 )
2020}
2121
2222// DomainHex Get the domain as hexadecimal string.
23- // Example: '0000'
23+ // Example: '0000', '10000', or 'deadbeef'
2424func (s * Address ) DomainHex () string {
25+ if s .Domain () > 65535 {
26+ // if domain is larger than 0xffff, don't cap output at 4 hex digits
27+ return fmt .Sprintf ("%x" , s .Domain ())
28+ }
2529 return fmt .Sprintf ("%04x" , s .Domain ())
2630}
2731
@@ -59,47 +63,59 @@ func (s *Address) Function() uint8 {
5963// FunctionHex Get the function as hexadecimal string.
6064// Example: '1'
6165func (s * Address ) FunctionHex () string {
62- return fmt .Sprintf ("%x" , s .Device ())
66+ return fmt .Sprintf ("%x" , s .Function ())
6367}
6468
6569// Hex Get the PCI Address in full human readable form.
6670// This includes the domain, bus, device, and function.
67- // Example: 0000:2f:00.1
71+ // Example: 0000:2f:00.1, or 10000:2f:00.1
6872func (s * Address ) Hex () string {
73+ if s .Domain () > 65535 {
74+ return fmt .Sprintf ("%x:%02x:%02x.%x" , s .Domain (), s .Bus (), s .Device (), s .Function ())
75+ }
6976 return fmt .Sprintf ("%04x:%02x:%02x.%x" , s .Domain (), s .Bus (), s .Device (), s .Function ())
7077}
7178
7279// AddrFromHex Parse a human readable PCI address
7380// into an Address struct. Omitting the domain
7481// defaults to '0000'.
75- // Expected formats: '0000:2f:00.1' or '2f:00.1'
82+ //
83+ // Expected formats: '10000:2f:00.1', '0000:2f:00.1', or '2f:00.1'
84+ // -> The domain is expected to be omitted OR 4-8 chars long
7685func AddrFromHex (addr string ) (* Address , error ) {
7786 if len (addr ) == 7 {
7887 addr = "0000:" + addr
7988 }
80- if len (addr ) != 12 {
89+ domainLength := len (addr ) - 8
90+ if domainLength < 4 || domainLength > 8 {
8191 return nil , fmt .Errorf ("unable to parse '%s' as pci address" , addr )
8292 }
83- domain , err := strconv .ParseUint (addr [:4 ], 16 , 16 )
93+ domain , err := strconv .ParseUint (addr [:domainLength ], 16 , 32 )
8494 if err != nil {
8595 return nil , fmt .Errorf ("unable to parse pci domain address" )
8696 }
87- bus , err := strconv .ParseUint (addr [5 :7 ], 16 , 8 )
97+ addr = addr [domainLength + 1 :]
98+ bus , err := strconv .ParseUint (addr [:2 ], 16 , 8 )
8899 if err != nil {
89- return nil , fmt .Errorf ("unable to parse pci bus address" )
100+ return nil , fmt .Errorf ("unable to parse pci bus address '%s'" , addr [: 2 ] )
90101 }
91- device , err := strconv .ParseUint (addr [8 :10 ], 16 , 8 )
102+ addr = addr [3 :]
103+ device , err := strconv .ParseUint (addr [:2 ], 16 , 8 )
92104 if err != nil {
93- return nil , fmt .Errorf ("unable to parse pci device address" )
105+ return nil , fmt .Errorf ("unable to parse pci device address '%s'" , addr [: 2 ] )
94106 }
95107 if device > 31 {
96108 return nil , fmt .Errorf ("the device can not be a number larger than 0x1f" )
97109 }
98- function , _ := strconv .ParseUint (addr [11 :12 ], 16 , 8 )
110+ addr = addr [3 :]
111+ function , err := strconv .ParseUint (addr [:1 ], 16 , 8 )
112+ if err != nil {
113+ return nil , fmt .Errorf ("unable to parse pci bus function '%s'" , addr [3 :])
114+ }
99115 if function > 7 {
100116 return nil , fmt .Errorf ("the function can not be a number larger than 0x7" )
101117 }
102118 return & Address {
103- Number : uint32 ((domain << 16 ) | (bus << 8 ) | (device << 3 ) | function ),
119+ Number : uint64 ((domain << 16 ) | (bus << 8 ) | (device << 3 ) | function ),
104120 }, nil
105121}
0 commit comments