1 // SPDX-License-Identifier: GPL-2.0 2 3 //! Abstractions for the PCI bus. 4 //! 5 //! C header: [`include/linux/pci.h`](srctree/include/linux/pci.h) 6 7 use crate::{ 8 alloc::flags::*, 9 bindings, container_of, device, 10 device_id::RawDeviceId, 11 devres::Devres, 12 driver, 13 error::{to_result, Result}, 14 io::Io, 15 io::IoRaw, 16 str::CStr, 17 types::{ARef, ForeignOwnable, Opaque}, 18 ThisModule, 19 }; 20 use core::{ops::Deref, ptr::addr_of_mut}; 21 use kernel::prelude::*; 22 23 /// An adapter for the registration of PCI drivers. 24 pub struct Adapter<T: Driver>(T); 25 26 impl<T: Driver + 'static> driver::RegistrationOps for Adapter<T> { 27 type RegType = bindings::pci_driver; 28 29 fn register( 30 pdrv: &Opaque<Self::RegType>, 31 name: &'static CStr, 32 module: &'static ThisModule, 33 ) -> Result { 34 // SAFETY: It's safe to set the fields of `struct pci_driver` on initialization. 35 unsafe { 36 (*pdrv.get()).name = name.as_char_ptr(); 37 (*pdrv.get()).probe = Some(Self::probe_callback); 38 (*pdrv.get()).remove = Some(Self::remove_callback); 39 (*pdrv.get()).id_table = T::ID_TABLE.as_ptr(); 40 } 41 42 // SAFETY: `pdrv` is guaranteed to be a valid `RegType`. 43 to_result(unsafe { 44 bindings::__pci_register_driver(pdrv.get(), module.0, name.as_char_ptr()) 45 }) 46 } 47 48 fn unregister(pdrv: &Opaque<Self::RegType>) { 49 // SAFETY: `pdrv` is guaranteed to be a valid `RegType`. 50 unsafe { bindings::pci_unregister_driver(pdrv.get()) } 51 } 52 } 53 54 impl<T: Driver + 'static> Adapter<T> { 55 extern "C" fn probe_callback( 56 pdev: *mut bindings::pci_dev, 57 id: *const bindings::pci_device_id, 58 ) -> kernel::ffi::c_int { 59 // SAFETY: The PCI bus only ever calls the probe callback with a valid pointer to a 60 // `struct pci_dev`. 61 let dev = unsafe { device::Device::get_device(addr_of_mut!((*pdev).dev)) }; 62 // SAFETY: `dev` is guaranteed to be embedded in a valid `struct pci_dev` by the call 63 // above. 64 let mut pdev = unsafe { Device::from_dev(dev) }; 65 66 // SAFETY: `DeviceId` is a `#[repr(transparent)` wrapper of `struct pci_device_id` and 67 // does not add additional invariants, so it's safe to transmute. 68 let id = unsafe { &*id.cast::<DeviceId>() }; 69 let info = T::ID_TABLE.info(id.index()); 70 71 match T::probe(&mut pdev, info) { 72 Ok(data) => { 73 // Let the `struct pci_dev` own a reference of the driver's private data. 74 // SAFETY: By the type invariant `pdev.as_raw` returns a valid pointer to a 75 // `struct pci_dev`. 76 unsafe { bindings::pci_set_drvdata(pdev.as_raw(), data.into_foreign() as _) }; 77 } 78 Err(err) => return Error::to_errno(err), 79 } 80 81 0 82 } 83 84 extern "C" fn remove_callback(pdev: *mut bindings::pci_dev) { 85 // SAFETY: The PCI bus only ever calls the remove callback with a valid pointer to a 86 // `struct pci_dev`. 87 let ptr = unsafe { bindings::pci_get_drvdata(pdev) }; 88 89 // SAFETY: `remove_callback` is only ever called after a successful call to 90 // `probe_callback`, hence it's guaranteed that `ptr` points to a valid and initialized 91 // `KBox<T>` pointer created through `KBox::into_foreign`. 92 let _ = unsafe { KBox::<T>::from_foreign(ptr) }; 93 } 94 } 95 96 /// Declares a kernel module that exposes a single PCI driver. 97 /// 98 /// # Example 99 /// 100 ///```ignore 101 /// kernel::module_pci_driver! { 102 /// type: MyDriver, 103 /// name: "Module name", 104 /// author: "Author name", 105 /// description: "Description", 106 /// license: "GPL v2", 107 /// } 108 ///``` 109 #[macro_export] 110 macro_rules! module_pci_driver { 111 ($($f:tt)*) => { 112 $crate::module_driver!(<T>, $crate::pci::Adapter<T>, { $($f)* }); 113 }; 114 } 115 116 /// Abstraction for bindings::pci_device_id. 117 #[repr(transparent)] 118 #[derive(Clone, Copy)] 119 pub struct DeviceId(bindings::pci_device_id); 120 121 impl DeviceId { 122 const PCI_ANY_ID: u32 = !0; 123 124 /// Equivalent to C's `PCI_DEVICE` macro. 125 /// 126 /// Create a new `pci::DeviceId` from a vendor and device ID number. 127 pub const fn from_id(vendor: u32, device: u32) -> Self { 128 Self(bindings::pci_device_id { 129 vendor, 130 device, 131 subvendor: DeviceId::PCI_ANY_ID, 132 subdevice: DeviceId::PCI_ANY_ID, 133 class: 0, 134 class_mask: 0, 135 driver_data: 0, 136 override_only: 0, 137 }) 138 } 139 140 /// Equivalent to C's `PCI_DEVICE_CLASS` macro. 141 /// 142 /// Create a new `pci::DeviceId` from a class number and mask. 143 pub const fn from_class(class: u32, class_mask: u32) -> Self { 144 Self(bindings::pci_device_id { 145 vendor: DeviceId::PCI_ANY_ID, 146 device: DeviceId::PCI_ANY_ID, 147 subvendor: DeviceId::PCI_ANY_ID, 148 subdevice: DeviceId::PCI_ANY_ID, 149 class, 150 class_mask, 151 driver_data: 0, 152 override_only: 0, 153 }) 154 } 155 } 156 157 // SAFETY: 158 // * `DeviceId` is a `#[repr(transparent)` wrapper of `pci_device_id` and does not add 159 // additional invariants, so it's safe to transmute to `RawType`. 160 // * `DRIVER_DATA_OFFSET` is the offset to the `driver_data` field. 161 unsafe impl RawDeviceId for DeviceId { 162 type RawType = bindings::pci_device_id; 163 164 const DRIVER_DATA_OFFSET: usize = core::mem::offset_of!(bindings::pci_device_id, driver_data); 165 166 fn index(&self) -> usize { 167 self.0.driver_data as _ 168 } 169 } 170 171 /// IdTable type for PCI 172 pub type IdTable<T> = &'static dyn kernel::device_id::IdTable<DeviceId, T>; 173 174 /// Create a PCI `IdTable` with its alias for modpost. 175 #[macro_export] 176 macro_rules! pci_device_table { 177 ($table_name:ident, $module_table_name:ident, $id_info_type: ty, $table_data: expr) => { 178 const $table_name: $crate::device_id::IdArray< 179 $crate::pci::DeviceId, 180 $id_info_type, 181 { $table_data.len() }, 182 > = $crate::device_id::IdArray::new($table_data); 183 184 $crate::module_device_table!("pci", $module_table_name, $table_name); 185 }; 186 } 187 188 /// The PCI driver trait. 189 /// 190 /// # Example 191 /// 192 ///``` 193 /// # use kernel::{bindings, pci}; 194 /// 195 /// struct MyDriver; 196 /// 197 /// kernel::pci_device_table!( 198 /// PCI_TABLE, 199 /// MODULE_PCI_TABLE, 200 /// <MyDriver as pci::Driver>::IdInfo, 201 /// [ 202 /// (pci::DeviceId::from_id(bindings::PCI_VENDOR_ID_REDHAT, bindings::PCI_ANY_ID as _), ()) 203 /// ] 204 /// ); 205 /// 206 /// impl pci::Driver for MyDriver { 207 /// type IdInfo = (); 208 /// const ID_TABLE: pci::IdTable<Self::IdInfo> = &PCI_TABLE; 209 /// 210 /// fn probe( 211 /// _pdev: &mut pci::Device, 212 /// _id_info: &Self::IdInfo, 213 /// ) -> Result<Pin<KBox<Self>>> { 214 /// Err(ENODEV) 215 /// } 216 /// } 217 ///``` 218 /// Drivers must implement this trait in order to get a PCI driver registered. Please refer to the 219 /// `Adapter` documentation for an example. 220 pub trait Driver { 221 /// The type holding information about each device id supported by the driver. 222 /// 223 /// TODO: Use associated_type_defaults once stabilized: 224 /// 225 /// type IdInfo: 'static = (); 226 type IdInfo: 'static; 227 228 /// The table of device ids supported by the driver. 229 const ID_TABLE: IdTable<Self::IdInfo>; 230 231 /// PCI driver probe. 232 /// 233 /// Called when a new platform device is added or discovered. 234 /// Implementers should attempt to initialize the device here. 235 fn probe(dev: &mut Device, id_info: &Self::IdInfo) -> Result<Pin<KBox<Self>>>; 236 } 237 238 /// The PCI device representation. 239 /// 240 /// A PCI device is based on an always reference counted `device:Device` instance. Cloning a PCI 241 /// device, hence, also increments the base device' reference count. 242 /// 243 /// # Invariants 244 /// 245 /// `Device` hold a valid reference of `ARef<device::Device>` whose underlying `struct device` is a 246 /// member of a `struct pci_dev`. 247 #[derive(Clone)] 248 pub struct Device(ARef<device::Device>); 249 250 /// A PCI BAR to perform I/O-Operations on. 251 /// 252 /// # Invariants 253 /// 254 /// `Bar` always holds an `IoRaw` inststance that holds a valid pointer to the start of the I/O 255 /// memory mapped PCI bar and its size. 256 pub struct Bar<const SIZE: usize = 0> { 257 pdev: Device, 258 io: IoRaw<SIZE>, 259 num: i32, 260 } 261 262 impl<const SIZE: usize> Bar<SIZE> { 263 fn new(pdev: Device, num: u32, name: &CStr) -> Result<Self> { 264 let len = pdev.resource_len(num)?; 265 if len == 0 { 266 return Err(ENOMEM); 267 } 268 269 // Convert to `i32`, since that's what all the C bindings use. 270 let num = i32::try_from(num)?; 271 272 // SAFETY: 273 // `pdev` is valid by the invariants of `Device`. 274 // `num` is checked for validity by a previous call to `Device::resource_len`. 275 // `name` is always valid. 276 let ret = unsafe { bindings::pci_request_region(pdev.as_raw(), num, name.as_char_ptr()) }; 277 if ret != 0 { 278 return Err(EBUSY); 279 } 280 281 // SAFETY: 282 // `pdev` is valid by the invariants of `Device`. 283 // `num` is checked for validity by a previous call to `Device::resource_len`. 284 // `name` is always valid. 285 let ioptr: usize = unsafe { bindings::pci_iomap(pdev.as_raw(), num, 0) } as usize; 286 if ioptr == 0 { 287 // SAFETY: 288 // `pdev` valid by the invariants of `Device`. 289 // `num` is checked for validity by a previous call to `Device::resource_len`. 290 unsafe { bindings::pci_release_region(pdev.as_raw(), num) }; 291 return Err(ENOMEM); 292 } 293 294 let io = match IoRaw::new(ioptr, len as usize) { 295 Ok(io) => io, 296 Err(err) => { 297 // SAFETY: 298 // `pdev` is valid by the invariants of `Device`. 299 // `ioptr` is guaranteed to be the start of a valid I/O mapped memory region. 300 // `num` is checked for validity by a previous call to `Device::resource_len`. 301 unsafe { Self::do_release(&pdev, ioptr, num) }; 302 return Err(err); 303 } 304 }; 305 306 Ok(Bar { pdev, io, num }) 307 } 308 309 /// # Safety 310 /// 311 /// `ioptr` must be a valid pointer to the memory mapped PCI bar number `num`. 312 unsafe fn do_release(pdev: &Device, ioptr: usize, num: i32) { 313 // SAFETY: 314 // `pdev` is valid by the invariants of `Device`. 315 // `ioptr` is valid by the safety requirements. 316 // `num` is valid by the safety requirements. 317 unsafe { 318 bindings::pci_iounmap(pdev.as_raw(), ioptr as _); 319 bindings::pci_release_region(pdev.as_raw(), num); 320 } 321 } 322 323 fn release(&self) { 324 // SAFETY: The safety requirements are guaranteed by the type invariant of `self.pdev`. 325 unsafe { Self::do_release(&self.pdev, self.io.addr(), self.num) }; 326 } 327 } 328 329 impl Bar { 330 fn index_is_valid(index: u32) -> bool { 331 // A `struct pci_dev` owns an array of resources with at most `PCI_NUM_RESOURCES` entries. 332 index < bindings::PCI_NUM_RESOURCES 333 } 334 } 335 336 impl<const SIZE: usize> Drop for Bar<SIZE> { 337 fn drop(&mut self) { 338 self.release(); 339 } 340 } 341 342 impl<const SIZE: usize> Deref for Bar<SIZE> { 343 type Target = Io<SIZE>; 344 345 fn deref(&self) -> &Self::Target { 346 // SAFETY: By the type invariant of `Self`, the MMIO range in `self.io` is properly mapped. 347 unsafe { Io::from_raw(&self.io) } 348 } 349 } 350 351 impl Device { 352 /// Create a PCI Device instance from an existing `device::Device`. 353 /// 354 /// # Safety 355 /// 356 /// `dev` must be an `ARef<device::Device>` whose underlying `bindings::device` is a member of 357 /// a `bindings::pci_dev`. 358 pub unsafe fn from_dev(dev: ARef<device::Device>) -> Self { 359 Self(dev) 360 } 361 362 fn as_raw(&self) -> *mut bindings::pci_dev { 363 // SAFETY: By the type invariant `self.0.as_raw` is a pointer to the `struct device` 364 // embedded in `struct pci_dev`. 365 unsafe { container_of!(self.0.as_raw(), bindings::pci_dev, dev) as _ } 366 } 367 368 /// Returns the PCI vendor ID. 369 pub fn vendor_id(&self) -> u16 { 370 // SAFETY: `self.as_raw` is a valid pointer to a `struct pci_dev`. 371 unsafe { (*self.as_raw()).vendor } 372 } 373 374 /// Returns the PCI device ID. 375 pub fn device_id(&self) -> u16 { 376 // SAFETY: `self.as_raw` is a valid pointer to a `struct pci_dev`. 377 unsafe { (*self.as_raw()).device } 378 } 379 380 /// Enable memory resources for this device. 381 pub fn enable_device_mem(&self) -> Result { 382 // SAFETY: `self.as_raw` is guaranteed to be a pointer to a valid `struct pci_dev`. 383 let ret = unsafe { bindings::pci_enable_device_mem(self.as_raw()) }; 384 if ret != 0 { 385 Err(Error::from_errno(ret)) 386 } else { 387 Ok(()) 388 } 389 } 390 391 /// Enable bus-mastering for this device. 392 pub fn set_master(&self) { 393 // SAFETY: `self.as_raw` is guaranteed to be a pointer to a valid `struct pci_dev`. 394 unsafe { bindings::pci_set_master(self.as_raw()) }; 395 } 396 397 /// Returns the size of the given PCI bar resource. 398 pub fn resource_len(&self, bar: u32) -> Result<bindings::resource_size_t> { 399 if !Bar::index_is_valid(bar) { 400 return Err(EINVAL); 401 } 402 403 // SAFETY: 404 // - `bar` is a valid bar number, as guaranteed by the above call to `Bar::index_is_valid`, 405 // - by its type invariant `self.as_raw` is always a valid pointer to a `struct pci_dev`. 406 Ok(unsafe { bindings::pci_resource_len(self.as_raw(), bar.try_into()?) }) 407 } 408 409 /// Mapps an entire PCI-BAR after performing a region-request on it. I/O operation bound checks 410 /// can be performed on compile time for offsets (plus the requested type size) < SIZE. 411 pub fn iomap_region_sized<const SIZE: usize>( 412 &self, 413 bar: u32, 414 name: &CStr, 415 ) -> Result<Devres<Bar<SIZE>>> { 416 let bar = Bar::<SIZE>::new(self.clone(), bar, name)?; 417 let devres = Devres::new(self.as_ref(), bar, GFP_KERNEL)?; 418 419 Ok(devres) 420 } 421 422 /// Mapps an entire PCI-BAR after performing a region-request on it. 423 pub fn iomap_region(&self, bar: u32, name: &CStr) -> Result<Devres<Bar>> { 424 self.iomap_region_sized::<0>(bar, name) 425 } 426 } 427 428 impl AsRef<device::Device> for Device { 429 fn as_ref(&self) -> &device::Device { 430 &self.0 431 } 432 } 433