1 use alloc::{ 2 string::String, 3 sync::{Arc, Weak}, 4 }; 5 use ida::IdAllocator; 6 use system_error::SystemError; 7 8 use crate::{ 9 driver::base::{ 10 class::Class, 11 device::{ 12 bus::Bus, device_manager, driver::Driver, Device, DeviceCommonData, DeviceType, IdTable, 13 }, 14 kobject::{KObjType, KObject, KObjectCommonData, KObjectState, LockedKObjectState}, 15 kset::KSet, 16 }, 17 filesystem::{ 18 kernfs::KernFSInode, 19 sysfs::{ 20 file::sysfs_emit_str, Attribute, AttributeGroup, SysFSOpsSupport, SYSFS_ATTR_MODE_RO, 21 }, 22 vfs::syscall::ModeType, 23 }, 24 libs::{ 25 rwlock::{RwLockReadGuard, RwLockWriteGuard}, 26 spinlock::{SpinLock, SpinLockGuard}, 27 }, 28 }; 29 30 use super::{ 31 class::sys_class_rtc_instance, 32 interface::rtc_read_time, 33 utils::{kobj2rtc_device, kobj2rtc_general_device}, 34 GeneralRtcPriority, RtcClassOps, RtcDevice, 35 }; 36 37 static RTC_GENERAL_DEVICE_IDA: IdAllocator = IdAllocator::new(0, usize::MAX); 38 39 pub(super) const RTC_HCTOSYS_DEVICE: &str = "rtc0"; 40 41 #[derive(Debug)] 42 #[cast_to([sync] KObject, Device, RtcDevice)] 43 pub struct RtcGeneralDevice { 44 name: String, 45 id: usize, 46 inner: SpinLock<InnerRtcGeneralDevice>, 47 kobj_state: LockedKObjectState, 48 priority: GeneralRtcPriority, 49 } 50 51 #[derive(Debug)] 52 struct InnerRtcGeneralDevice { 53 device_common: DeviceCommonData, 54 kobject_common: KObjectCommonData, 55 56 class_ops: Option<&'static dyn RtcClassOps>, 57 /// 上一次调用`rtc_hctosys()`把时间同步到timekeeper的时候的返回值 58 hc2sysfs_result: Result<(), SystemError>, 59 } 60 61 impl RtcGeneralDevice { 62 /// 创建一个新的通用RTC设备实例 63 /// 64 /// 注意,由于还需要进行其他的初始化操作,因此这个函数并不是公开的构造函数。 65 fn new(priority: GeneralRtcPriority) -> Arc<Self> { 66 let id = RTC_GENERAL_DEVICE_IDA.alloc().unwrap(); 67 let name = format!("rtc{}", id); 68 Arc::new(Self { 69 name, 70 id, 71 inner: SpinLock::new(InnerRtcGeneralDevice { 72 device_common: DeviceCommonData::default(), 73 kobject_common: KObjectCommonData::default(), 74 class_ops: None, 75 hc2sysfs_result: Err(SystemError::ENODEV), 76 }), 77 kobj_state: LockedKObjectState::new(None), 78 priority, 79 }) 80 } 81 82 fn inner(&self) -> SpinLockGuard<InnerRtcGeneralDevice> { 83 self.inner.lock() 84 } 85 86 pub fn set_class_ops(&self, class_ops: &'static dyn RtcClassOps) { 87 self.inner().class_ops = Some(class_ops); 88 } 89 90 pub fn class_ops(&self) -> Option<&'static dyn RtcClassOps> { 91 self.inner().class_ops 92 } 93 94 pub fn priority(&self) -> GeneralRtcPriority { 95 self.priority 96 } 97 98 pub(super) fn set_hc2sys_result(&self, val: Result<(), SystemError>) { 99 self.inner().hc2sysfs_result = val; 100 } 101 102 pub(super) fn hc2sysfs_result(&self) -> Result<(), SystemError> { 103 self.inner().hc2sysfs_result.clone() 104 } 105 } 106 107 impl Drop for RtcGeneralDevice { 108 fn drop(&mut self) { 109 RTC_GENERAL_DEVICE_IDA.free(self.id); 110 } 111 } 112 113 impl RtcDevice for RtcGeneralDevice { 114 fn class_ops(&self) -> &'static dyn super::RtcClassOps { 115 todo!() 116 } 117 } 118 119 impl Device for RtcGeneralDevice { 120 fn dev_type(&self) -> DeviceType { 121 DeviceType::Rtc 122 } 123 124 fn id_table(&self) -> IdTable { 125 IdTable::new(self.name.clone(), None) 126 } 127 128 fn set_bus(&self, bus: Option<Weak<dyn Bus>>) { 129 self.inner().device_common.bus = bus; 130 } 131 132 fn bus(&self) -> Option<Weak<dyn Bus>> { 133 self.inner().device_common.get_bus_weak_or_clear() 134 } 135 136 fn set_class(&self, class: Option<Weak<dyn Class>>) { 137 self.inner().device_common.class = class; 138 } 139 140 fn class(&self) -> Option<Arc<dyn Class>> { 141 self.inner() 142 .device_common 143 .get_class_weak_or_clear() 144 .and_then(|x| x.upgrade()) 145 } 146 147 fn driver(&self) -> Option<Arc<dyn Driver>> { 148 self.inner() 149 .device_common 150 .get_driver_weak_or_clear() 151 .and_then(|x| x.upgrade()) 152 } 153 154 fn set_driver(&self, driver: Option<Weak<dyn Driver>>) { 155 self.inner().device_common.driver = driver; 156 } 157 158 fn is_dead(&self) -> bool { 159 false 160 } 161 162 fn can_match(&self) -> bool { 163 false 164 } 165 166 fn set_can_match(&self, _can_match: bool) { 167 // do nothing 168 } 169 170 fn state_synced(&self) -> bool { 171 true 172 } 173 fn attribute_groups(&self) -> Option<&'static [&'static dyn AttributeGroup]> { 174 Some(&[&RtcAttrGroup]) 175 } 176 177 fn dev_parent(&self) -> Option<Weak<dyn Device>> { 178 self.inner().device_common.get_parent_weak_or_clear() 179 } 180 181 fn set_dev_parent(&self, dev_parent: Option<Weak<dyn Device>>) { 182 self.inner().device_common.parent = dev_parent; 183 } 184 } 185 186 impl KObject for RtcGeneralDevice { 187 fn as_any_ref(&self) -> &dyn core::any::Any { 188 self 189 } 190 191 fn set_inode(&self, inode: Option<Arc<KernFSInode>>) { 192 self.inner().kobject_common.kern_inode = inode; 193 } 194 195 fn inode(&self) -> Option<Arc<KernFSInode>> { 196 self.inner().kobject_common.kern_inode.clone() 197 } 198 199 fn parent(&self) -> Option<Weak<dyn KObject>> { 200 self.inner().kobject_common.parent.clone() 201 } 202 203 fn set_parent(&self, parent: Option<Weak<dyn KObject>>) { 204 self.inner().kobject_common.parent = parent; 205 } 206 207 fn kset(&self) -> Option<Arc<KSet>> { 208 self.inner().kobject_common.kset.clone() 209 } 210 211 fn set_kset(&self, kset: Option<Arc<KSet>>) { 212 self.inner().kobject_common.kset = kset; 213 } 214 215 fn kobj_type(&self) -> Option<&'static dyn KObjType> { 216 self.inner().kobject_common.kobj_type 217 } 218 219 fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) { 220 self.inner().kobject_common.kobj_type = ktype; 221 } 222 223 fn name(&self) -> String { 224 self.name.clone() 225 } 226 227 fn set_name(&self, _name: String) { 228 // do nothing 229 } 230 231 fn kobj_state(&self) -> RwLockReadGuard<KObjectState> { 232 self.kobj_state.read() 233 } 234 235 fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> { 236 self.kobj_state.write() 237 } 238 239 fn set_kobj_state(&self, state: KObjectState) { 240 *self.kobj_state_mut() = state; 241 } 242 } 243 244 /// 245 /// 用于创建一个通用的RTC设备实例。 246 /// 247 /// ## 参数 248 /// 249 /// - `real_dev`: 一个对实际RTC设备的引用,这个设备将作为通用RTC设备的父设备。 250 pub fn rtc_general_device_create( 251 real_dev: &Arc<dyn RtcDevice>, 252 priority: Option<GeneralRtcPriority>, 253 ) -> Arc<RtcGeneralDevice> { 254 let dev = RtcGeneralDevice::new(priority.unwrap_or_default()); 255 device_manager().device_default_initialize(&(dev.clone() as Arc<dyn Device>)); 256 dev.set_dev_parent(Some(Arc::downgrade(real_dev) as Weak<dyn Device>)); 257 dev.set_class(Some(Arc::downgrade( 258 &(sys_class_rtc_instance().cloned().unwrap() as Arc<dyn Class>), 259 ))); 260 261 return dev; 262 } 263 264 #[derive(Debug)] 265 struct RtcAttrGroup; 266 267 impl AttributeGroup for RtcAttrGroup { 268 fn name(&self) -> Option<&str> { 269 None 270 } 271 272 fn attrs(&self) -> &[&'static dyn Attribute] { 273 &[&AttrName, &AttrDate, &AttrTime, &AttrHcToSys] 274 } 275 276 fn is_visible( 277 &self, 278 _kobj: Arc<dyn KObject>, 279 attr: &'static dyn Attribute, 280 ) -> Option<ModeType> { 281 // todo: https://code.dragonos.org.cn/xref/linux-6.6.21/drivers/rtc/sysfs.c#280 282 283 return Some(attr.mode()); 284 } 285 } 286 287 #[derive(Debug)] 288 struct AttrName; 289 290 impl Attribute for AttrName { 291 fn name(&self) -> &str { 292 "name" 293 } 294 295 fn mode(&self) -> ModeType { 296 SYSFS_ATTR_MODE_RO 297 } 298 299 fn support(&self) -> SysFSOpsSupport { 300 SysFSOpsSupport::ATTR_SHOW 301 } 302 303 fn show(&self, kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> { 304 let rtc_device = kobj 305 .parent() 306 .and_then(|x| x.upgrade()) 307 .ok_or(SystemError::ENODEV)?; 308 let rtc_device = kobj2rtc_device(rtc_device).ok_or(SystemError::EINVAL)?; 309 310 let driver_name = rtc_device.driver().ok_or(SystemError::ENODEV)?.name(); 311 let device_name = rtc_device.name(); 312 sysfs_emit_str(buf, &format!("{} {}\n", driver_name, device_name)) 313 } 314 } 315 316 #[derive(Debug)] 317 struct AttrDate; 318 319 impl Attribute for AttrDate { 320 fn name(&self) -> &str { 321 "date" 322 } 323 324 fn mode(&self) -> ModeType { 325 SYSFS_ATTR_MODE_RO 326 } 327 328 fn support(&self) -> SysFSOpsSupport { 329 SysFSOpsSupport::ATTR_SHOW 330 } 331 332 fn show(&self, kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> { 333 let rtc_device: Arc<RtcGeneralDevice> = 334 kobj2rtc_general_device(kobj).ok_or(SystemError::EINVAL)?; 335 let time = rtc_read_time(&rtc_device)?; 336 sysfs_emit_str(buf, &time.date_string()) 337 } 338 } 339 340 #[derive(Debug)] 341 struct AttrTime; 342 343 impl Attribute for AttrTime { 344 fn name(&self) -> &str { 345 "time" 346 } 347 348 fn mode(&self) -> ModeType { 349 SYSFS_ATTR_MODE_RO 350 } 351 352 fn support(&self) -> SysFSOpsSupport { 353 SysFSOpsSupport::ATTR_SHOW 354 } 355 356 fn show(&self, kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> { 357 let rtc_device = kobj2rtc_general_device(kobj).ok_or(SystemError::EINVAL)?; 358 let time = rtc_read_time(&rtc_device)?; 359 sysfs_emit_str(buf, &time.time_string()) 360 } 361 } 362 363 #[derive(Debug)] 364 struct AttrHcToSys; 365 366 impl Attribute for AttrHcToSys { 367 fn name(&self) -> &str { 368 "hctosys" 369 } 370 371 fn mode(&self) -> ModeType { 372 SYSFS_ATTR_MODE_RO 373 } 374 375 fn support(&self) -> SysFSOpsSupport { 376 SysFSOpsSupport::ATTR_SHOW 377 } 378 379 fn show(&self, kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> { 380 let rtc_device = kobj2rtc_general_device(kobj).ok_or(SystemError::EINVAL)?; 381 if rtc_device.hc2sysfs_result().is_ok() && rtc_device.name().eq(RTC_HCTOSYS_DEVICE) { 382 return sysfs_emit_str(buf, "1\n"); 383 } 384 385 return sysfs_emit_str(buf, "0\n"); 386 } 387 } 388