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