dev_id.rs 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. use alloc::sync::Arc;
  2. use super::device::PciDevice;
  3. const PCI_ANY_ID: u32 = 0xffff_ffff;
  4. /// # 结构功能
  5. /// 该结构用于驱动和设备之间的识别,驱动会有一个支持的设备ID列表,而设备会自带一个ID,如果设备的ID在驱动的支持列表中,则驱动和设备就可以识别了
  6. /// 见https://code.dragonos.org.cn/xref/linux-6.1.9/include/linux/mod_devicetable.h#43
  7. #[derive(Debug, Copy, Clone)]
  8. pub struct PciDeviceID {
  9. vendor: u32,
  10. device_id: u32,
  11. subvendor: u32,
  12. subdevice: u32,
  13. class: u32,
  14. class_mask: u32,
  15. _driver_data: u64,
  16. _override_only: u32,
  17. /// 可能有些设备的识别方式比较特殊,那么可以通过设置该字段进行自定义的识别方式,只需要在PciSpecifiedData枚举中加入一个类型即可
  18. /// 若该字段不为None,则优先使用special_data进行识别;
  19. /// 该字段是为了增加灵活性
  20. special_data: Option<PciSpecifiedData>,
  21. }
  22. impl PciDeviceID {
  23. #[allow(dead_code)]
  24. pub fn set_special(&mut self, data: PciSpecifiedData) {
  25. self.special_data = Some(data);
  26. }
  27. pub fn dummpy() -> Self {
  28. return Self {
  29. vendor: PCI_ANY_ID,
  30. device_id: PCI_ANY_ID,
  31. subvendor: PCI_ANY_ID,
  32. subdevice: PCI_ANY_ID,
  33. class: PCI_ANY_ID,
  34. class_mask: PCI_ANY_ID,
  35. _driver_data: 0,
  36. _override_only: PCI_ANY_ID,
  37. special_data: None,
  38. };
  39. }
  40. pub fn match_dev(&self, dev: &Arc<dyn PciDevice>) -> bool {
  41. if let Some(d_data) = &dev.dynid().special_data {
  42. return d_data.match_dev(self.special_data);
  43. }
  44. if let Some(s_data) = &self.special_data {
  45. return s_data.match_dev(dev.dynid().special_data);
  46. } else {
  47. let d_id = dev.dynid();
  48. return self.general_match(d_id);
  49. }
  50. }
  51. /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/pci/pci.h?fi=pci_match_one_device#195
  52. pub fn general_match(&self, id: PciDeviceID) -> bool {
  53. if (self.vendor == id.vendor() || self.vendor == PCI_ANY_ID)
  54. && (self.device_id == id.device_id() || self.device_id == PCI_ANY_ID)
  55. && (self.subvendor == id.subvendor() || self.subvendor == PCI_ANY_ID)
  56. && (self.subdevice == id.subdevice() || self.subdevice == PCI_ANY_ID)
  57. && self.class_check(&id)
  58. {
  59. return true;
  60. }
  61. return false;
  62. }
  63. pub fn class_check(&self, id: &Self) -> bool {
  64. return (self.class ^ id.class()) & self.class_mask == 0;
  65. }
  66. pub fn vendor(&self) -> u32 {
  67. self.vendor
  68. }
  69. pub fn device_id(&self) -> u32 {
  70. self.device_id
  71. }
  72. pub fn subvendor(&self) -> u32 {
  73. self.subvendor
  74. }
  75. pub fn subdevice(&self) -> u32 {
  76. self.subdevice
  77. }
  78. pub fn class(&self) -> u32 {
  79. self.class
  80. }
  81. pub fn _class_mask(&self) -> u32 {
  82. self.class_mask
  83. }
  84. }
  85. #[derive(PartialEq, Eq, PartialOrd, Ord, Debug, Copy, Clone)]
  86. pub enum PciSpecifiedData {}
  87. impl PciSpecifiedData {
  88. pub fn match_dev(&self, data: Option<Self>) -> bool {
  89. if let Some(data) = data {
  90. return *self == data;
  91. } else {
  92. return false;
  93. }
  94. }
  95. }