forked from sonic-net/sonic-platform-common
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy patheeprom_dts.py
143 lines (117 loc) · 4.21 KB
/
eeprom_dts.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# Copyright 2012 Cumulus Networks LLC, all rights reserved
try:
import exceptions # Python 2
except ImportError:
import builtins as exceptions # Python 3
try:
import os
import binascii
import subprocess
except ImportError as e:
raise ImportError (str(e) + "- required module not found")
i2c_root = '/sys/class/i2c-adapter/'
mtd_root = '/dev/mtd'
dts_root = '/proc/device-tree/'
sys_dev = '/sys/devices/'
#
# This routine takes a token list containing the desired eeprom types
# (e.g. 'sfp', 'psu', 'board'), and returns a dict of {[dts path:(dev attrs)]}
# for the corresponding eeproms. For those accessible via i2c, the attrs
# will contain (i2c bus index, i2c device number). For those mounted to
# /dev/mtd, the attrs will be (mtd partition number).
#
def get_dev_attr_from_dtb(tokens):
dts_paths = []
i2c_devices = []
sub_devices = []
eep_dict = {}
#
# first try i2c
#
try:
ph = subprocess.Popen(['/bin/ls', '-R', dts_root],
stdout=subprocess.PIPE,
shell=False, stderr=subprocess.STDOUT)
cmdout = ph.communicate()[0]
ph.wait()
except OSError as e:
raise OSError("cannot access directory")
lines = cmdout.splitlines()
for I in lines:
if not I.endswith(':') or 'i2c' not in I:
continue
I = I.rstrip(':\n\r')
last = I.split('/')[-1]
if 'i2c' in last:
depth = I.count('i2c')
while len(sub_devices) < depth:
sub_devices.append([])
sub_devices[depth-1].append(I)
elif 'eeprom' in last:
dts_paths.append(I)
# re-order the device heirarchy and build the device list
for i in sub_devices:
for j in i:
i2c_devices.append(j)
for eep in dts_paths:
instance = ''
if os.path.isfile('/'.join([eep, 'label'])):
F = open('/'.join([eep, 'label']), "rb")
instance = F.read().partition('_eeprom')[0]
F.close()
# check for read-only
read_only = os.path.isfile('/'.join([eep, 'read-only']))
for t in tokens:
if t not in eep and t not in instance:
continue
# get the i2c idx by matching the path prefix
i2c_idx = i2c_devices.index(eep.rsplit('/', 1)[0])
# read the reg
reg_path = '/'.join([eep, 'reg'])
F = open(reg_path, "rb")
o = F.read()
reg = binascii.b2a_hex(o)[-2:]
F.close()
eep_dict[eep] = {'type': 'i2c', \
'dev-id': i2c_idx, \
'reg': reg, \
'ro': read_only}
break
#
# now try flash
#
try:
ph = subprocess.Popen(['/bin/grep', '-r', 'eeprom', dts_root],
stdout=subprocess.PIPE,
shell=False, stderr=subprocess.STDOUT)
cmdout = ph.communicate()[0]
ph.wait()
except OSError as e:
raise OSError("cannot access directory")
lines = cmdout.splitlines()
for I in lines:
if 'flash' not in I or 'label' not in I:
continue
eep = I.partition(dts_root)[2].rpartition('label')[0]
full_eep = '/'.join([dts_root, eep])
F = open('/'.join([full_eep, 'label']), "rb")
instance = F.read().partition('_eeprom')[0]
F.close()
read_only = os.path.isfile('/'.join([full_eep, 'read-only']))
for t in tokens:
if t not in instance:
continue
mtd_n = eep.partition('partition@')[2].rstrip('/')
eep_dict[full_eep] = {'type': 'mtd', \
'dev-id': mtd_n, \
'ro': read_only}
return eep_dict
def dev_attr_to_path(dev_attrs):
dev_path = ''
if dev_attrs['type'] == 'i2c':
dev_path = i2c_root + 'i2c-' + str(dev_attrs['dev-id']) + '/' + \
str(dev_attrs['dev-id']) + '-00' + str(dev_attrs['reg']) + \
'/' + 'eeprom'
elif dev_attrs['type'] == 'mtd':
dev_path = mtd_root + dev_attrs['dev-id']
return dev_path