@@ -154,6 +154,129 @@ static ssize_t resource_show(struct device *dev, struct device_attribute *attr,
154154}
155155static DEVICE_ATTR_RO (resource );
156156
157+ static ssize_t max_link_speed_show (struct device * dev ,
158+ struct device_attribute * attr , char * buf )
159+ {
160+ struct pci_dev * pci_dev = to_pci_dev (dev );
161+ u32 linkcap ;
162+ int err ;
163+ const char * speed ;
164+
165+ err = pcie_capability_read_dword (pci_dev , PCI_EXP_LNKCAP , & linkcap );
166+ if (err )
167+ return - EINVAL ;
168+
169+ switch (linkcap & PCI_EXP_LNKCAP_SLS ) {
170+ case PCI_EXP_LNKCAP_SLS_8_0GB :
171+ speed = "8 GT/s" ;
172+ break ;
173+ case PCI_EXP_LNKCAP_SLS_5_0GB :
174+ speed = "5 GT/s" ;
175+ break ;
176+ case PCI_EXP_LNKCAP_SLS_2_5GB :
177+ speed = "2.5 GT/s" ;
178+ break ;
179+ default :
180+ speed = "Unknown speed" ;
181+ }
182+
183+ return sprintf (buf , "%s\n" , speed );
184+ }
185+ static DEVICE_ATTR_RO (max_link_speed );
186+
187+ static ssize_t max_link_width_show (struct device * dev ,
188+ struct device_attribute * attr , char * buf )
189+ {
190+ struct pci_dev * pci_dev = to_pci_dev (dev );
191+ u32 linkcap ;
192+ int err ;
193+
194+ err = pcie_capability_read_dword (pci_dev , PCI_EXP_LNKCAP , & linkcap );
195+ if (err )
196+ return - EINVAL ;
197+
198+ return sprintf (buf , "%u\n" , (linkcap & PCI_EXP_LNKCAP_MLW ) >> 4 );
199+ }
200+ static DEVICE_ATTR_RO (max_link_width );
201+
202+ static ssize_t current_link_speed_show (struct device * dev ,
203+ struct device_attribute * attr , char * buf )
204+ {
205+ struct pci_dev * pci_dev = to_pci_dev (dev );
206+ u16 linkstat ;
207+ int err ;
208+ const char * speed ;
209+
210+ err = pcie_capability_read_word (pci_dev , PCI_EXP_LNKSTA , & linkstat );
211+ if (err )
212+ return - EINVAL ;
213+
214+ switch (linkstat & PCI_EXP_LNKSTA_CLS ) {
215+ case PCI_EXP_LNKSTA_CLS_8_0GB :
216+ speed = "8 GT/s" ;
217+ break ;
218+ case PCI_EXP_LNKSTA_CLS_5_0GB :
219+ speed = "5 GT/s" ;
220+ break ;
221+ case PCI_EXP_LNKSTA_CLS_2_5GB :
222+ speed = "2.5 GT/s" ;
223+ break ;
224+ default :
225+ speed = "Unknown speed" ;
226+ }
227+
228+ return sprintf (buf , "%s\n" , speed );
229+ }
230+ static DEVICE_ATTR_RO (current_link_speed );
231+
232+ static ssize_t current_link_width_show (struct device * dev ,
233+ struct device_attribute * attr , char * buf )
234+ {
235+ struct pci_dev * pci_dev = to_pci_dev (dev );
236+ u16 linkstat ;
237+ int err ;
238+
239+ err = pcie_capability_read_word (pci_dev , PCI_EXP_LNKSTA , & linkstat );
240+ if (err )
241+ return - EINVAL ;
242+
243+ return sprintf (buf , "%u\n" ,
244+ (linkstat & PCI_EXP_LNKSTA_NLW ) >> PCI_EXP_LNKSTA_NLW_SHIFT );
245+ }
246+ static DEVICE_ATTR_RO (current_link_width );
247+
248+ static ssize_t secondary_bus_number_show (struct device * dev ,
249+ struct device_attribute * attr ,
250+ char * buf )
251+ {
252+ struct pci_dev * pci_dev = to_pci_dev (dev );
253+ u8 sec_bus ;
254+ int err ;
255+
256+ err = pci_read_config_byte (pci_dev , PCI_SECONDARY_BUS , & sec_bus );
257+ if (err )
258+ return - EINVAL ;
259+
260+ return sprintf (buf , "%u\n" , sec_bus );
261+ }
262+ static DEVICE_ATTR_RO (secondary_bus_number );
263+
264+ static ssize_t subordinate_bus_number_show (struct device * dev ,
265+ struct device_attribute * attr ,
266+ char * buf )
267+ {
268+ struct pci_dev * pci_dev = to_pci_dev (dev );
269+ u8 sub_bus ;
270+ int err ;
271+
272+ err = pci_read_config_byte (pci_dev , PCI_SUBORDINATE_BUS , & sub_bus );
273+ if (err )
274+ return - EINVAL ;
275+
276+ return sprintf (buf , "%u\n" , sub_bus );
277+ }
278+ static DEVICE_ATTR_RO (subordinate_bus_number );
279+
157280static ssize_t modalias_show (struct device * dev , struct device_attribute * attr ,
158281 char * buf )
159282{
@@ -629,12 +752,17 @@ static struct attribute *pci_dev_attrs[] = {
629752 NULL ,
630753};
631754
632- static const struct attribute_group pci_dev_group = {
633- .attrs = pci_dev_attrs ,
755+ static struct attribute * pci_bridge_attrs [] = {
756+ & dev_attr_subordinate_bus_number .attr ,
757+ & dev_attr_secondary_bus_number .attr ,
758+ NULL ,
634759};
635760
636- const struct attribute_group * pci_dev_groups [] = {
637- & pci_dev_group ,
761+ static struct attribute * pcie_dev_attrs [] = {
762+ & dev_attr_current_link_speed .attr ,
763+ & dev_attr_current_link_width .attr ,
764+ & dev_attr_max_link_width .attr ,
765+ & dev_attr_max_link_speed .attr ,
638766 NULL ,
639767};
640768
@@ -1557,6 +1685,57 @@ static umode_t pci_dev_hp_attrs_are_visible(struct kobject *kobj,
15571685 return a -> mode ;
15581686}
15591687
1688+ static umode_t pci_bridge_attrs_are_visible (struct kobject * kobj ,
1689+ struct attribute * a , int n )
1690+ {
1691+ struct device * dev = kobj_to_dev (kobj );
1692+ struct pci_dev * pdev = to_pci_dev (dev );
1693+
1694+ if (pci_is_bridge (pdev ))
1695+ return a -> mode ;
1696+
1697+ return 0 ;
1698+ }
1699+
1700+ static umode_t pcie_dev_attrs_are_visible (struct kobject * kobj ,
1701+ struct attribute * a , int n )
1702+ {
1703+ struct device * dev = kobj_to_dev (kobj );
1704+ struct pci_dev * pdev = to_pci_dev (dev );
1705+
1706+ if (pci_is_pcie (pdev ))
1707+ return a -> mode ;
1708+
1709+ return 0 ;
1710+ }
1711+
1712+ static const struct attribute_group pci_dev_group = {
1713+ .attrs = pci_dev_attrs ,
1714+ };
1715+
1716+ const struct attribute_group * pci_dev_groups [] = {
1717+ & pci_dev_group ,
1718+ NULL ,
1719+ };
1720+
1721+ static const struct attribute_group pci_bridge_group = {
1722+ .attrs = pci_bridge_attrs ,
1723+ };
1724+
1725+ const struct attribute_group * pci_bridge_groups [] = {
1726+ & pci_bridge_group ,
1727+ NULL ,
1728+ };
1729+
1730+ static const struct attribute_group pcie_dev_group = {
1731+ .attrs = pcie_dev_attrs ,
1732+ };
1733+
1734+ const struct attribute_group * pcie_dev_groups [] = {
1735+ & pcie_dev_group ,
1736+ NULL ,
1737+ };
1738+
15601739static struct attribute_group pci_dev_hp_attr_group = {
15611740 .attrs = pci_dev_hp_attrs ,
15621741 .is_visible = pci_dev_hp_attrs_are_visible ,
@@ -1592,12 +1771,24 @@ static struct attribute_group pci_dev_attr_group = {
15921771 .is_visible = pci_dev_attrs_are_visible ,
15931772};
15941773
1774+ static struct attribute_group pci_bridge_attr_group = {
1775+ .attrs = pci_bridge_attrs ,
1776+ .is_visible = pci_bridge_attrs_are_visible ,
1777+ };
1778+
1779+ static struct attribute_group pcie_dev_attr_group = {
1780+ .attrs = pcie_dev_attrs ,
1781+ .is_visible = pcie_dev_attrs_are_visible ,
1782+ };
1783+
15951784static const struct attribute_group * pci_dev_attr_groups [] = {
15961785 & pci_dev_attr_group ,
15971786 & pci_dev_hp_attr_group ,
15981787#ifdef CONFIG_PCI_IOV
15991788 & sriov_dev_attr_group ,
16001789#endif
1790+ & pci_bridge_attr_group ,
1791+ & pcie_dev_attr_group ,
16011792 NULL ,
16021793};
16031794
0 commit comments