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 178 impl KObject for RtcGeneralDevice { 179 fn as_any_ref(&self) -> &dyn core::any::Any { 180 self 181 } 182 183 fn set_inode(&self, inode: Option<Arc<KernFSInode>>) { 184 self.inner().kobject_common.kern_inode = inode; 185 } 186 187 fn inode(&self) -> Option<Arc<KernFSInode>> { 188 self.inner().kobject_common.kern_inode.clone() 189 } 190 191 fn parent(&self) -> Option<Weak<dyn KObject>> { 192 self.inner().kobject_common.parent.clone() 193 } 194 195 fn set_parent(&self, parent: Option<Weak<dyn KObject>>) { 196 self.inner().kobject_common.parent = parent; 197 } 198 199 fn kset(&self) -> Option<Arc<KSet>> { 200 self.inner().kobject_common.kset.clone() 201 } 202 203 fn set_kset(&self, kset: Option<Arc<KSet>>) { 204 self.inner().kobject_common.kset = kset; 205 } 206 207 fn kobj_type(&self) -> Option<&'static dyn KObjType> { 208 self.inner().kobject_common.kobj_type 209 } 210 211 fn set_kobj_type(&self, ktype: Option<&'static dyn KObjType>) { 212 self.inner().kobject_common.kobj_type = ktype; 213 } 214 215 fn name(&self) -> String { 216 self.name.clone() 217 } 218 219 fn set_name(&self, _name: String) { 220 // do nothing 221 } 222 223 fn kobj_state(&self) -> RwLockReadGuard<KObjectState> { 224 self.kobj_state.read() 225 } 226 227 fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> { 228 self.kobj_state.write() 229 } 230 231 fn set_kobj_state(&self, state: KObjectState) { 232 *self.kobj_state_mut() = state; 233 } 234 } 235 236 /// 237 /// 用于创建一个通用的RTC设备实例。 238 /// 239 /// ## 参数 240 /// 241 /// - `real_dev`: 一个对实际RTC设备的引用,这个设备将作为通用RTC设备的父设备。 242 pub fn rtc_general_device_create( 243 real_dev: &Arc<dyn RtcDevice>, 244 priority: Option<GeneralRtcPriority>, 245 ) -> Arc<RtcGeneralDevice> { 246 let dev = RtcGeneralDevice::new(priority.unwrap_or_default()); 247 device_manager().device_default_initialize(&(dev.clone() as Arc<dyn Device>)); 248 dev.set_parent(Some(Arc::downgrade(real_dev) as Weak<dyn KObject>)); 249 dev.set_class(Some(Arc::downgrade( 250 &(sys_class_rtc_instance().cloned().unwrap() as Arc<dyn Class>), 251 ))); 252 253 return dev; 254 } 255 256 #[derive(Debug)] 257 struct RtcAttrGroup; 258 259 impl AttributeGroup for RtcAttrGroup { 260 fn name(&self) -> Option<&str> { 261 None 262 } 263 264 fn attrs(&self) -> &[&'static dyn Attribute] { 265 &[&AttrName, &AttrDate, &AttrTime, &AttrHcToSys] 266 } 267 268 fn is_visible( 269 &self, 270 _kobj: Arc<dyn KObject>, 271 attr: &'static dyn Attribute, 272 ) -> Option<ModeType> { 273 // todo: https://code.dragonos.org.cn/xref/linux-6.6.21/drivers/rtc/sysfs.c#280 274 275 return Some(attr.mode()); 276 } 277 } 278 279 #[derive(Debug)] 280 struct AttrName; 281 282 impl Attribute for AttrName { 283 fn name(&self) -> &str { 284 "name" 285 } 286 287 fn mode(&self) -> ModeType { 288 SYSFS_ATTR_MODE_RO 289 } 290 291 fn support(&self) -> SysFSOpsSupport { 292 SysFSOpsSupport::ATTR_SHOW 293 } 294 295 fn show(&self, kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> { 296 let rtc_device = kobj 297 .parent() 298 .and_then(|x| x.upgrade()) 299 .ok_or(SystemError::ENODEV)?; 300 let rtc_device = kobj2rtc_device(rtc_device).ok_or(SystemError::EINVAL)?; 301 302 let driver_name = rtc_device.driver().ok_or(SystemError::ENODEV)?.name(); 303 let device_name = rtc_device.name(); 304 sysfs_emit_str(buf, &format!("{} {}\n", driver_name, device_name)) 305 } 306 } 307 308 #[derive(Debug)] 309 struct AttrDate; 310 311 impl Attribute for AttrDate { 312 fn name(&self) -> &str { 313 "date" 314 } 315 316 fn mode(&self) -> ModeType { 317 SYSFS_ATTR_MODE_RO 318 } 319 320 fn support(&self) -> SysFSOpsSupport { 321 SysFSOpsSupport::ATTR_SHOW 322 } 323 324 fn show(&self, kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> { 325 let rtc_device: Arc<RtcGeneralDevice> = 326 kobj2rtc_general_device(kobj).ok_or(SystemError::EINVAL)?; 327 let time = rtc_read_time(&rtc_device)?; 328 sysfs_emit_str(buf, &time.date_string()) 329 } 330 } 331 332 #[derive(Debug)] 333 struct AttrTime; 334 335 impl Attribute for AttrTime { 336 fn name(&self) -> &str { 337 "time" 338 } 339 340 fn mode(&self) -> ModeType { 341 SYSFS_ATTR_MODE_RO 342 } 343 344 fn support(&self) -> SysFSOpsSupport { 345 SysFSOpsSupport::ATTR_SHOW 346 } 347 348 fn show(&self, kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> { 349 let rtc_device = kobj2rtc_general_device(kobj).ok_or(SystemError::EINVAL)?; 350 let time = rtc_read_time(&rtc_device)?; 351 sysfs_emit_str(buf, &time.time_string()) 352 } 353 } 354 355 #[derive(Debug)] 356 struct AttrHcToSys; 357 358 impl Attribute for AttrHcToSys { 359 fn name(&self) -> &str { 360 "hctosys" 361 } 362 363 fn mode(&self) -> ModeType { 364 SYSFS_ATTR_MODE_RO 365 } 366 367 fn support(&self) -> SysFSOpsSupport { 368 SysFSOpsSupport::ATTR_SHOW 369 } 370 371 fn show(&self, kobj: Arc<dyn KObject>, buf: &mut [u8]) -> Result<usize, SystemError> { 372 let rtc_device = kobj2rtc_general_device(kobj).ok_or(SystemError::EINVAL)?; 373 if rtc_device.hc2sysfs_result().is_ok() && rtc_device.name().eq(RTC_HCTOSYS_DEVICE) { 374 return sysfs_emit_str(buf, "1\n"); 375 } 376 377 return sysfs_emit_str(buf, "0\n"); 378 } 379 } 380