xref: /linux/rust/kernel/pci/id.rs (revision ed78a01887e2257cff0412b640db68b70a2654dc)
1 // SPDX-License-Identifier: GPL-2.0
2 
3 //! PCI device identifiers and related types.
4 //!
5 //! This module contains PCI class codes and supporting types.
6 
7 use crate::{bindings, error::code::EINVAL, error::Error, prelude::*};
8 use core::fmt;
9 
10 /// PCI device class codes.
11 ///
12 /// Each entry contains the full 24-bit PCI class code (base class in bits
13 /// 23-16, subclass in bits 15-8, programming interface in bits 7-0).
14 ///
15 /// # Examples
16 ///
17 /// ```
18 /// # use kernel::{device::Core, pci::{self, Class}, prelude::*};
19 /// fn probe_device(pdev: &pci::Device<Core>) -> Result {
20 ///     let pci_class = pdev.pci_class();
21 ///     dev_info!(
22 ///         pdev.as_ref(),
23 ///         "Detected PCI class: {}\n",
24 ///         pci_class
25 ///     );
26 ///     Ok(())
27 /// }
28 /// ```
29 #[derive(Clone, Copy, PartialEq, Eq)]
30 #[repr(transparent)]
31 pub struct Class(u32);
32 
33 /// PCI class mask constants for matching [`Class`] codes.
34 #[repr(u32)]
35 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
36 pub enum ClassMask {
37     /// Match the full 24-bit class code.
38     Full = 0xffffff,
39     /// Match the upper 16 bits of the class code (base class and subclass only)
40     ClassSubclass = 0xffff00,
41 }
42 
43 macro_rules! define_all_pci_classes {
44     (
45         $($variant:ident = $binding:expr,)+
46     ) => {
47         impl Class {
48             $(
49                 #[allow(missing_docs)]
50                 pub const $variant: Self = Self(Self::to_24bit_class($binding));
51             )+
52         }
53     };
54 }
55 
56 /// Once constructed, a [`Class`] contains a valid PCI class code.
57 impl Class {
58     /// Create a [`Class`] from a raw 24-bit class code.
59     #[inline]
60     pub(super) fn from_raw(class_code: u32) -> Self {
61         Self(class_code)
62     }
63 
64     /// Get the raw 24-bit class code value.
65     #[inline]
66     pub const fn as_raw(self) -> u32 {
67         self.0
68     }
69 
70     // Converts a PCI class constant to 24-bit format.
71     //
72     // Many device drivers use only the upper 16 bits (base class and subclass),
73     // but some use the full 24 bits. In order to support both cases, store the
74     // class code as a 24-bit value, where 16-bit values are shifted up 8 bits.
75     const fn to_24bit_class(val: u32) -> u32 {
76         if val > 0xFFFF {
77             val
78         } else {
79             val << 8
80         }
81     }
82 }
83 
84 impl fmt::Debug for Class {
85     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
86         write!(f, "0x{:06x}", self.0)
87     }
88 }
89 
90 impl fmt::Display for Class {
91     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
92         <Self as fmt::Debug>::fmt(self, f)
93     }
94 }
95 
96 impl ClassMask {
97     /// Get the raw mask value.
98     #[inline]
99     pub const fn as_raw(self) -> u32 {
100         self as u32
101     }
102 }
103 
104 impl TryFrom<u32> for ClassMask {
105     type Error = Error;
106 
107     fn try_from(value: u32) -> Result<Self, Self::Error> {
108         match value {
109             0xffffff => Ok(ClassMask::Full),
110             0xffff00 => Ok(ClassMask::ClassSubclass),
111             _ => Err(EINVAL),
112         }
113     }
114 }
115 
116 define_all_pci_classes! {
117     NOT_DEFINED                = bindings::PCI_CLASS_NOT_DEFINED,                // 0x000000
118     NOT_DEFINED_VGA            = bindings::PCI_CLASS_NOT_DEFINED_VGA,            // 0x000100
119 
120     STORAGE_SCSI               = bindings::PCI_CLASS_STORAGE_SCSI,               // 0x010000
121     STORAGE_IDE                = bindings::PCI_CLASS_STORAGE_IDE,                // 0x010100
122     STORAGE_FLOPPY             = bindings::PCI_CLASS_STORAGE_FLOPPY,             // 0x010200
123     STORAGE_IPI                = bindings::PCI_CLASS_STORAGE_IPI,                // 0x010300
124     STORAGE_RAID               = bindings::PCI_CLASS_STORAGE_RAID,               // 0x010400
125     STORAGE_SATA               = bindings::PCI_CLASS_STORAGE_SATA,               // 0x010600
126     STORAGE_SATA_AHCI          = bindings::PCI_CLASS_STORAGE_SATA_AHCI,          // 0x010601
127     STORAGE_SAS                = bindings::PCI_CLASS_STORAGE_SAS,                // 0x010700
128     STORAGE_EXPRESS            = bindings::PCI_CLASS_STORAGE_EXPRESS,            // 0x010802
129     STORAGE_OTHER              = bindings::PCI_CLASS_STORAGE_OTHER,              // 0x018000
130 
131     NETWORK_ETHERNET           = bindings::PCI_CLASS_NETWORK_ETHERNET,           // 0x020000
132     NETWORK_TOKEN_RING         = bindings::PCI_CLASS_NETWORK_TOKEN_RING,         // 0x020100
133     NETWORK_FDDI               = bindings::PCI_CLASS_NETWORK_FDDI,               // 0x020200
134     NETWORK_ATM                = bindings::PCI_CLASS_NETWORK_ATM,                // 0x020300
135     NETWORK_OTHER              = bindings::PCI_CLASS_NETWORK_OTHER,              // 0x028000
136 
137     DISPLAY_VGA                = bindings::PCI_CLASS_DISPLAY_VGA,                // 0x030000
138     DISPLAY_XGA                = bindings::PCI_CLASS_DISPLAY_XGA,                // 0x030100
139     DISPLAY_3D                 = bindings::PCI_CLASS_DISPLAY_3D,                 // 0x030200
140     DISPLAY_OTHER              = bindings::PCI_CLASS_DISPLAY_OTHER,              // 0x038000
141 
142     MULTIMEDIA_VIDEO           = bindings::PCI_CLASS_MULTIMEDIA_VIDEO,           // 0x040000
143     MULTIMEDIA_AUDIO           = bindings::PCI_CLASS_MULTIMEDIA_AUDIO,           // 0x040100
144     MULTIMEDIA_PHONE           = bindings::PCI_CLASS_MULTIMEDIA_PHONE,           // 0x040200
145     MULTIMEDIA_HD_AUDIO        = bindings::PCI_CLASS_MULTIMEDIA_HD_AUDIO,        // 0x040300
146     MULTIMEDIA_OTHER           = bindings::PCI_CLASS_MULTIMEDIA_OTHER,           // 0x048000
147 
148     MEMORY_RAM                 = bindings::PCI_CLASS_MEMORY_RAM,                 // 0x050000
149     MEMORY_FLASH               = bindings::PCI_CLASS_MEMORY_FLASH,               // 0x050100
150     MEMORY_CXL                 = bindings::PCI_CLASS_MEMORY_CXL,                 // 0x050200
151     MEMORY_OTHER               = bindings::PCI_CLASS_MEMORY_OTHER,               // 0x058000
152 
153     BRIDGE_HOST                = bindings::PCI_CLASS_BRIDGE_HOST,                // 0x060000
154     BRIDGE_ISA                 = bindings::PCI_CLASS_BRIDGE_ISA,                 // 0x060100
155     BRIDGE_EISA                = bindings::PCI_CLASS_BRIDGE_EISA,                // 0x060200
156     BRIDGE_MC                  = bindings::PCI_CLASS_BRIDGE_MC,                  // 0x060300
157     BRIDGE_PCI_NORMAL          = bindings::PCI_CLASS_BRIDGE_PCI_NORMAL,          // 0x060400
158     BRIDGE_PCI_SUBTRACTIVE     = bindings::PCI_CLASS_BRIDGE_PCI_SUBTRACTIVE,     // 0x060401
159     BRIDGE_PCMCIA              = bindings::PCI_CLASS_BRIDGE_PCMCIA,              // 0x060500
160     BRIDGE_NUBUS               = bindings::PCI_CLASS_BRIDGE_NUBUS,               // 0x060600
161     BRIDGE_CARDBUS             = bindings::PCI_CLASS_BRIDGE_CARDBUS,             // 0x060700
162     BRIDGE_RACEWAY             = bindings::PCI_CLASS_BRIDGE_RACEWAY,             // 0x060800
163     BRIDGE_OTHER               = bindings::PCI_CLASS_BRIDGE_OTHER,               // 0x068000
164 
165     COMMUNICATION_SERIAL       = bindings::PCI_CLASS_COMMUNICATION_SERIAL,       // 0x070000
166     COMMUNICATION_PARALLEL     = bindings::PCI_CLASS_COMMUNICATION_PARALLEL,     // 0x070100
167     COMMUNICATION_MULTISERIAL  = bindings::PCI_CLASS_COMMUNICATION_MULTISERIAL,  // 0x070200
168     COMMUNICATION_MODEM        = bindings::PCI_CLASS_COMMUNICATION_MODEM,        // 0x070300
169     COMMUNICATION_OTHER        = bindings::PCI_CLASS_COMMUNICATION_OTHER,        // 0x078000
170 
171     SYSTEM_PIC                 = bindings::PCI_CLASS_SYSTEM_PIC,                 // 0x080000
172     SYSTEM_PIC_IOAPIC          = bindings::PCI_CLASS_SYSTEM_PIC_IOAPIC,          // 0x080010
173     SYSTEM_PIC_IOXAPIC         = bindings::PCI_CLASS_SYSTEM_PIC_IOXAPIC,         // 0x080020
174     SYSTEM_DMA                 = bindings::PCI_CLASS_SYSTEM_DMA,                 // 0x080100
175     SYSTEM_TIMER               = bindings::PCI_CLASS_SYSTEM_TIMER,               // 0x080200
176     SYSTEM_RTC                 = bindings::PCI_CLASS_SYSTEM_RTC,                 // 0x080300
177     SYSTEM_PCI_HOTPLUG         = bindings::PCI_CLASS_SYSTEM_PCI_HOTPLUG,         // 0x080400
178     SYSTEM_SDHCI               = bindings::PCI_CLASS_SYSTEM_SDHCI,               // 0x080500
179     SYSTEM_RCEC                = bindings::PCI_CLASS_SYSTEM_RCEC,                // 0x080700
180     SYSTEM_OTHER               = bindings::PCI_CLASS_SYSTEM_OTHER,               // 0x088000
181 
182     INPUT_KEYBOARD             = bindings::PCI_CLASS_INPUT_KEYBOARD,             // 0x090000
183     INPUT_PEN                  = bindings::PCI_CLASS_INPUT_PEN,                  // 0x090100
184     INPUT_MOUSE                = bindings::PCI_CLASS_INPUT_MOUSE,                // 0x090200
185     INPUT_SCANNER              = bindings::PCI_CLASS_INPUT_SCANNER,              // 0x090300
186     INPUT_GAMEPORT             = bindings::PCI_CLASS_INPUT_GAMEPORT,             // 0x090400
187     INPUT_OTHER                = bindings::PCI_CLASS_INPUT_OTHER,                // 0x098000
188 
189     DOCKING_GENERIC            = bindings::PCI_CLASS_DOCKING_GENERIC,            // 0x0a0000
190     DOCKING_OTHER              = bindings::PCI_CLASS_DOCKING_OTHER,              // 0x0a8000
191 
192     PROCESSOR_386              = bindings::PCI_CLASS_PROCESSOR_386,              // 0x0b0000
193     PROCESSOR_486              = bindings::PCI_CLASS_PROCESSOR_486,              // 0x0b0100
194     PROCESSOR_PENTIUM          = bindings::PCI_CLASS_PROCESSOR_PENTIUM,          // 0x0b0200
195     PROCESSOR_ALPHA            = bindings::PCI_CLASS_PROCESSOR_ALPHA,            // 0x0b1000
196     PROCESSOR_POWERPC          = bindings::PCI_CLASS_PROCESSOR_POWERPC,          // 0x0b2000
197     PROCESSOR_MIPS             = bindings::PCI_CLASS_PROCESSOR_MIPS,             // 0x0b3000
198     PROCESSOR_CO               = bindings::PCI_CLASS_PROCESSOR_CO,               // 0x0b4000
199 
200     SERIAL_FIREWIRE            = bindings::PCI_CLASS_SERIAL_FIREWIRE,            // 0x0c0000
201     SERIAL_FIREWIRE_OHCI       = bindings::PCI_CLASS_SERIAL_FIREWIRE_OHCI,       // 0x0c0010
202     SERIAL_ACCESS              = bindings::PCI_CLASS_SERIAL_ACCESS,              // 0x0c0100
203     SERIAL_SSA                 = bindings::PCI_CLASS_SERIAL_SSA,                 // 0x0c0200
204     SERIAL_USB_UHCI            = bindings::PCI_CLASS_SERIAL_USB_UHCI,            // 0x0c0300
205     SERIAL_USB_OHCI            = bindings::PCI_CLASS_SERIAL_USB_OHCI,            // 0x0c0310
206     SERIAL_USB_EHCI            = bindings::PCI_CLASS_SERIAL_USB_EHCI,            // 0x0c0320
207     SERIAL_USB_XHCI            = bindings::PCI_CLASS_SERIAL_USB_XHCI,            // 0x0c0330
208     SERIAL_USB_CDNS            = bindings::PCI_CLASS_SERIAL_USB_CDNS,            // 0x0c0380
209     SERIAL_USB_DEVICE          = bindings::PCI_CLASS_SERIAL_USB_DEVICE,          // 0x0c03fe
210     SERIAL_FIBER               = bindings::PCI_CLASS_SERIAL_FIBER,               // 0x0c0400
211     SERIAL_SMBUS               = bindings::PCI_CLASS_SERIAL_SMBUS,               // 0x0c0500
212     SERIAL_IPMI_SMIC           = bindings::PCI_CLASS_SERIAL_IPMI_SMIC,           // 0x0c0700
213     SERIAL_IPMI_KCS            = bindings::PCI_CLASS_SERIAL_IPMI_KCS,            // 0x0c0701
214     SERIAL_IPMI_BT             = bindings::PCI_CLASS_SERIAL_IPMI_BT,             // 0x0c0702
215 
216     WIRELESS_RF_CONTROLLER     = bindings::PCI_CLASS_WIRELESS_RF_CONTROLLER,     // 0x0d1000
217     WIRELESS_WHCI              = bindings::PCI_CLASS_WIRELESS_WHCI,              // 0x0d1010
218 
219     INTELLIGENT_I2O            = bindings::PCI_CLASS_INTELLIGENT_I2O,            // 0x0e0000
220 
221     SATELLITE_TV               = bindings::PCI_CLASS_SATELLITE_TV,               // 0x0f0000
222     SATELLITE_AUDIO            = bindings::PCI_CLASS_SATELLITE_AUDIO,            // 0x0f0100
223     SATELLITE_VOICE            = bindings::PCI_CLASS_SATELLITE_VOICE,            // 0x0f0300
224     SATELLITE_DATA             = bindings::PCI_CLASS_SATELLITE_DATA,             // 0x0f0400
225 
226     CRYPT_NETWORK              = bindings::PCI_CLASS_CRYPT_NETWORK,              // 0x100000
227     CRYPT_ENTERTAINMENT        = bindings::PCI_CLASS_CRYPT_ENTERTAINMENT,        // 0x100100
228     CRYPT_OTHER                = bindings::PCI_CLASS_CRYPT_OTHER,                // 0x108000
229 
230     SP_DPIO                    = bindings::PCI_CLASS_SP_DPIO,                    // 0x110000
231     SP_OTHER                   = bindings::PCI_CLASS_SP_OTHER,                   // 0x118000
232 
233     ACCELERATOR_PROCESSING     = bindings::PCI_CLASS_ACCELERATOR_PROCESSING,     // 0x120000
234 
235     OTHERS                     = bindings::PCI_CLASS_OTHERS,                     // 0xff0000
236 }
237