xref: /DragonOS/kernel/src/driver/disk/ahci/ahcidisk.rs (revision 28fe4ad2a0b0d8b5abf1f0cb402b1c3204b42242)
1816ee5aeSLoGin use super::{_port, hba::HbaCmdTable};
2816ee5aeSLoGin use crate::arch::MMArch;
39fa0e95eSLoGin use crate::driver::base::block::block_device::{
49fa0e95eSLoGin     BlockDevName, BlockDevice, BlockId, GeneralBlockRange,
59fa0e95eSLoGin };
6b087521eSChiichen use crate::driver::base::block::disk_info::Partition;
79fa0e95eSLoGin use crate::driver::base::block::manager::BlockDevMeta;
808a2ee40SLoGin use crate::driver::base::class::Class;
906d5e247SLoGin use crate::driver::base::device::bus::Bus;
10ad1d649eSGnoCiYeH 
11a03c4f9dSLoGin use crate::driver::base::device::driver::Driver;
1206d5e247SLoGin use crate::driver::base::device::{Device, DeviceType, IdTable};
1306d5e247SLoGin use crate::driver::base::kobject::{KObjType, KObject, KObjectState};
1406d5e247SLoGin use crate::driver::base::kset::KSet;
15004e86ffSlogin use crate::driver::disk::ahci::HBA_PxIS_TFES;
16a03c4f9dSLoGin 
179fa0e95eSLoGin use crate::driver::scsi::scsi_manager;
1806d5e247SLoGin use crate::filesystem::kernfs::KernFSInode;
19004e86ffSlogin use crate::filesystem::mbr::MbrDiskPartionTable;
20004e86ffSlogin 
212eab6dd7S曾俊 use crate::driver::disk::ahci::hba::{
222eab6dd7S曾俊     FisRegH2D, FisType, HbaCmdHeader, ATA_CMD_READ_DMA_EXT, ATA_CMD_WRITE_DMA_EXT, ATA_DEV_BUSY,
232eab6dd7S曾俊     ATA_DEV_DRQ,
242eab6dd7S曾俊 };
2506d5e247SLoGin use crate::libs::rwlock::{RwLockReadGuard, RwLockWriteGuard};
269fa0e95eSLoGin use crate::libs::spinlock::{SpinLock, SpinLockGuard};
27816ee5aeSLoGin use crate::mm::{verify_area, MemoryManagementArch, PhysAddr, VirtAddr};
282eab6dd7S曾俊 use log::error;
2991e9d4abSLoGin use system_error::SystemError;
30004e86ffSlogin 
31004e86ffSlogin use alloc::sync::Weak;
329fa0e95eSLoGin use alloc::{sync::Arc, vec::Vec};
33004e86ffSlogin 
34004e86ffSlogin use core::fmt::Debug;
357ae679ddSLoGin use core::sync::atomic::{compiler_fence, Ordering};
36004e86ffSlogin use core::{mem::size_of, ptr::write_bytes};
37004e86ffSlogin 
38004e86ffSlogin /// @brief: 只支持MBR分区格式的磁盘结构体
39004e86ffSlogin pub struct AhciDisk {
409fa0e95eSLoGin     // 磁盘的状态flags
41004e86ffSlogin     pub partitions: Vec<Arc<Partition>>, // 磁盘分区数组
42004e86ffSlogin     // port: &'static mut HbaPort,      // 控制硬盘的端口
43004e86ffSlogin     pub ctrl_num: u8,
44004e86ffSlogin     pub port_num: u8,
45004e86ffSlogin     /// 指向LockAhciDisk的弱引用
46004e86ffSlogin     self_ref: Weak<LockedAhciDisk>,
47004e86ffSlogin }
48004e86ffSlogin 
49004e86ffSlogin /// @brief: 带锁的AhciDisk
50004e86ffSlogin #[derive(Debug)]
519fa0e95eSLoGin pub struct LockedAhciDisk {
529fa0e95eSLoGin     blkdev_meta: BlockDevMeta,
539fa0e95eSLoGin     inner: SpinLock<AhciDisk>,
549fa0e95eSLoGin }
559fa0e95eSLoGin 
569fa0e95eSLoGin impl LockedAhciDisk {
inner(&self) -> SpinLockGuard<AhciDisk>579fa0e95eSLoGin     pub fn inner(&self) -> SpinLockGuard<AhciDisk> {
589fa0e95eSLoGin         self.inner.lock()
599fa0e95eSLoGin     }
609fa0e95eSLoGin }
619fa0e95eSLoGin 
62004e86ffSlogin /// 函数实现
63004e86ffSlogin impl Debug for AhciDisk {
fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result64004e86ffSlogin     fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
659fa0e95eSLoGin         write!(f, "AhciDisk")
66004e86ffSlogin     }
67004e86ffSlogin }
68004e86ffSlogin 
69004e86ffSlogin impl AhciDisk {
read_at( &self, lba_id_start: BlockId, count: usize, buf: &mut [u8], ) -> Result<usize, SystemError>70004e86ffSlogin     fn read_at(
71004e86ffSlogin         &self,
72b087521eSChiichen         lba_id_start: BlockId, // 起始lba编号
73004e86ffSlogin         count: usize,          // 读取lba的数量
74004e86ffSlogin         buf: &mut [u8],
75676b8ef6SMork     ) -> Result<usize, SystemError> {
767ae679ddSLoGin         assert!((buf.len() & 511) == 0);
77731bc2b3SLoGin         compiler_fence(Ordering::SeqCst);
78004e86ffSlogin         let check_length = ((count - 1) >> 4) + 1; // prdt length
79b5b571e0SLoGin         if count * 512 > buf.len() || check_length > 8_usize {
802eab6dd7S曾俊             error!("ahci read: e2big");
81004e86ffSlogin             // 不可能的操作
82676b8ef6SMork             return Err(SystemError::E2BIG);
83004e86ffSlogin         } else if count == 0 {
84004e86ffSlogin             return Ok(0);
85004e86ffSlogin         }
86004e86ffSlogin 
87004e86ffSlogin         let port = _port(self.ctrl_num, self.port_num);
88004e86ffSlogin         volatile_write!(port.is, u32::MAX); // Clear pending interrupt bits
89004e86ffSlogin 
90004e86ffSlogin         let slot = port.find_cmdslot().unwrap_or(u32::MAX);
91004e86ffSlogin 
92004e86ffSlogin         if slot == u32::MAX {
93676b8ef6SMork             return Err(SystemError::EIO);
94004e86ffSlogin         }
95004e86ffSlogin 
96004e86ffSlogin         #[allow(unused_unsafe)]
97004e86ffSlogin         let cmdheader: &mut HbaCmdHeader = unsafe {
98816ee5aeSLoGin             (MMArch::phys_2_virt(PhysAddr::new(
99b5b571e0SLoGin                 volatile_read!(port.clb) as usize + slot as usize * size_of::<HbaCmdHeader>(),
100816ee5aeSLoGin             ))
101816ee5aeSLoGin             .unwrap()
102816ee5aeSLoGin             .data() as *mut HbaCmdHeader)
103004e86ffSlogin                 .as_mut()
104004e86ffSlogin                 .unwrap()
105004e86ffSlogin         };
106004e86ffSlogin 
1077ae679ddSLoGin         cmdheader.cfl = (size_of::<FisRegH2D>() / size_of::<u32>()) as u8;
108004e86ffSlogin 
109004e86ffSlogin         volatile_set_bit!(cmdheader.cfl, 1 << 6, false); //  Read/Write bit : Read from device
110004e86ffSlogin         volatile_write!(cmdheader.prdtl, check_length as u16); // PRDT entries count
111004e86ffSlogin 
112004e86ffSlogin         // 设置数据存放地址
113004e86ffSlogin         let mut buf_ptr = buf as *mut [u8] as *mut usize as usize;
114660a04ceSlogin 
115660a04ceSlogin         // 由于目前的内存管理机制无法把用户空间的内存地址转换为物理地址,所以只能先把数据拷贝到内核空间
116660a04ceSlogin         // TODO:在内存管理重构后,可以直接使用用户空间的内存地址
1174fda81ceSLoGin 
118b5b571e0SLoGin         let user_buf = verify_area(VirtAddr::new(buf_ptr), buf.len()).is_ok();
119660a04ceSlogin         let mut kbuf = if user_buf {
120b5b571e0SLoGin             let x: Vec<u8> = vec![0; buf.len()];
121660a04ceSlogin             Some(x)
122660a04ceSlogin         } else {
123660a04ceSlogin             None
124660a04ceSlogin         };
125660a04ceSlogin 
126660a04ceSlogin         if kbuf.is_some() {
127660a04ceSlogin             buf_ptr = kbuf.as_mut().unwrap().as_mut_ptr() as usize;
128660a04ceSlogin         }
129660a04ceSlogin 
130004e86ffSlogin         #[allow(unused_unsafe)]
131004e86ffSlogin         let cmdtbl = unsafe {
132816ee5aeSLoGin             (MMArch::phys_2_virt(PhysAddr::new(volatile_read!(cmdheader.ctba) as usize))
133816ee5aeSLoGin                 .unwrap()
134816ee5aeSLoGin                 .data() as *mut HbaCmdTable)
135004e86ffSlogin                 .as_mut()
136004e86ffSlogin                 .unwrap() // 必须使用 as_mut ,得到的才是原来的变量
137004e86ffSlogin         };
138004e86ffSlogin         let mut tmp_count = count;
139004e86ffSlogin 
140004e86ffSlogin         unsafe {
141004e86ffSlogin             // 清空整个table的旧数据
142004e86ffSlogin             write_bytes(cmdtbl, 0, 1);
143004e86ffSlogin         }
1442eab6dd7S曾俊         // debug!("cmdheader.prdtl={}", volatile_read!(cmdheader.prdtl));
145004e86ffSlogin 
146004e86ffSlogin         // 8K bytes (16 sectors) per PRDT
147004e86ffSlogin         for i in 0..((volatile_read!(cmdheader.prdtl) - 1) as usize) {
148816ee5aeSLoGin             volatile_write!(
149816ee5aeSLoGin                 cmdtbl.prdt_entry[i].dba,
150816ee5aeSLoGin                 MMArch::virt_2_phys(VirtAddr::new(buf_ptr)).unwrap().data() as u64
151816ee5aeSLoGin             );
1527ae679ddSLoGin             cmdtbl.prdt_entry[i].dbc = 8 * 1024 - 1;
153004e86ffSlogin             volatile_set_bit!(cmdtbl.prdt_entry[i].dbc, 1 << 31, true); // 允许中断 prdt_entry.i
154004e86ffSlogin             buf_ptr += 8 * 1024;
155004e86ffSlogin             tmp_count -= 16;
156004e86ffSlogin         }
157004e86ffSlogin 
158004e86ffSlogin         // Last entry
159004e86ffSlogin         let las = (volatile_read!(cmdheader.prdtl) - 1) as usize;
160816ee5aeSLoGin         volatile_write!(
161816ee5aeSLoGin             cmdtbl.prdt_entry[las].dba,
162816ee5aeSLoGin             MMArch::virt_2_phys(VirtAddr::new(buf_ptr)).unwrap().data() as u64
163816ee5aeSLoGin         );
1647ae679ddSLoGin         cmdtbl.prdt_entry[las].dbc = ((tmp_count << 9) - 1) as u32; // 数据长度
1657ae679ddSLoGin 
166004e86ffSlogin         volatile_set_bit!(cmdtbl.prdt_entry[las].dbc, 1 << 31, true); // 允许中断
167004e86ffSlogin 
168004e86ffSlogin         // 设置命令
169004e86ffSlogin         let cmdfis = unsafe {
170004e86ffSlogin             ((&mut cmdtbl.cfis) as *mut [u8] as *mut usize as *mut FisRegH2D)
171004e86ffSlogin                 .as_mut()
172004e86ffSlogin                 .unwrap()
173004e86ffSlogin         };
174004e86ffSlogin         volatile_write!(cmdfis.fis_type, FisType::RegH2D as u8);
175004e86ffSlogin         volatile_set_bit!(cmdfis.pm, 1 << 7, true); // command_bit set
176004e86ffSlogin         volatile_write!(cmdfis.command, ATA_CMD_READ_DMA_EXT);
177004e86ffSlogin 
178004e86ffSlogin         volatile_write!(cmdfis.lba0, (lba_id_start & 0xFF) as u8);
179004e86ffSlogin         volatile_write!(cmdfis.lba1, ((lba_id_start >> 8) & 0xFF) as u8);
180004e86ffSlogin         volatile_write!(cmdfis.lba2, ((lba_id_start >> 16) & 0xFF) as u8);
181004e86ffSlogin         volatile_write!(cmdfis.lba3, ((lba_id_start >> 24) & 0xFF) as u8);
182004e86ffSlogin         volatile_write!(cmdfis.lba4, ((lba_id_start >> 32) & 0xFF) as u8);
183004e86ffSlogin         volatile_write!(cmdfis.lba5, ((lba_id_start >> 40) & 0xFF) as u8);
184004e86ffSlogin 
185004e86ffSlogin         volatile_write!(cmdfis.countl, (count & 0xFF) as u8);
186004e86ffSlogin         volatile_write!(cmdfis.counth, ((count >> 8) & 0xFF) as u8);
187004e86ffSlogin 
188004e86ffSlogin         volatile_write!(cmdfis.device, 1 << 6); // LBA Mode
189004e86ffSlogin 
190004e86ffSlogin         // 等待之前的操作完成
191004e86ffSlogin         let mut spin_count = 0;
192004e86ffSlogin         const SPIN_LIMIT: u32 = 10000;
193004e86ffSlogin 
194004e86ffSlogin         while (volatile_read!(port.tfd) as u8 & (ATA_DEV_BUSY | ATA_DEV_DRQ)) > 0
195004e86ffSlogin             && spin_count < SPIN_LIMIT
196004e86ffSlogin         {
197004e86ffSlogin             spin_count += 1;
198004e86ffSlogin         }
199004e86ffSlogin 
200004e86ffSlogin         if spin_count == SPIN_LIMIT {
2012eab6dd7S曾俊             error!("Port is hung");
202676b8ef6SMork             return Err(SystemError::EIO);
203004e86ffSlogin         }
204004e86ffSlogin 
205004e86ffSlogin         volatile_set_bit!(port.ci, 1 << slot, true); // Issue command
2062eab6dd7S曾俊                                                      // debug!("To wait ahci read complete.");
207004e86ffSlogin                                                      // 等待操作完成
208004e86ffSlogin         loop {
209004e86ffSlogin             if (volatile_read!(port.ci) & (1 << slot)) == 0 {
210004e86ffSlogin                 break;
211004e86ffSlogin             }
212004e86ffSlogin             if (volatile_read!(port.is) & HBA_PxIS_TFES) > 0 {
2132eab6dd7S曾俊                 error!("Read disk error");
214676b8ef6SMork                 return Err(SystemError::EIO);
215004e86ffSlogin             }
216004e86ffSlogin         }
217bd70d2d1SLoGin         if let Some(kbuf) = &kbuf {
218bd70d2d1SLoGin             buf.copy_from_slice(kbuf);
219660a04ceSlogin         }
220660a04ceSlogin 
221731bc2b3SLoGin         compiler_fence(Ordering::SeqCst);
222004e86ffSlogin         // successfully read
223004e86ffSlogin         return Ok(count * 512);
224004e86ffSlogin     }
225004e86ffSlogin 
write_at( &self, lba_id_start: BlockId, count: usize, buf: &[u8], ) -> Result<usize, SystemError>226004e86ffSlogin     fn write_at(
227004e86ffSlogin         &self,
228b087521eSChiichen         lba_id_start: BlockId,
229004e86ffSlogin         count: usize,
230004e86ffSlogin         buf: &[u8],
231676b8ef6SMork     ) -> Result<usize, SystemError> {
2327ae679ddSLoGin         assert!((buf.len() & 511) == 0);
233731bc2b3SLoGin         compiler_fence(Ordering::SeqCst);
234004e86ffSlogin         let check_length = ((count - 1) >> 4) + 1; // prdt length
235b5b571e0SLoGin         if count * 512 > buf.len() || check_length > 8 {
236004e86ffSlogin             // 不可能的操作
237676b8ef6SMork             return Err(SystemError::E2BIG);
238004e86ffSlogin         } else if count == 0 {
239004e86ffSlogin             return Ok(0);
240004e86ffSlogin         }
241004e86ffSlogin 
242004e86ffSlogin         let port = _port(self.ctrl_num, self.port_num);
243004e86ffSlogin 
244004e86ffSlogin         volatile_write!(port.is, u32::MAX); // Clear pending interrupt bits
245004e86ffSlogin 
246004e86ffSlogin         let slot = port.find_cmdslot().unwrap_or(u32::MAX);
247004e86ffSlogin 
248004e86ffSlogin         if slot == u32::MAX {
249676b8ef6SMork             return Err(SystemError::EIO);
250004e86ffSlogin         }
251004e86ffSlogin 
252731bc2b3SLoGin         compiler_fence(Ordering::SeqCst);
253004e86ffSlogin         #[allow(unused_unsafe)]
254004e86ffSlogin         let cmdheader: &mut HbaCmdHeader = unsafe {
255816ee5aeSLoGin             (MMArch::phys_2_virt(PhysAddr::new(
256b5b571e0SLoGin                 volatile_read!(port.clb) as usize + slot as usize * size_of::<HbaCmdHeader>(),
257816ee5aeSLoGin             ))
258816ee5aeSLoGin             .unwrap()
259816ee5aeSLoGin             .data() as *mut HbaCmdHeader)
260004e86ffSlogin                 .as_mut()
261004e86ffSlogin                 .unwrap()
262004e86ffSlogin         };
263731bc2b3SLoGin         compiler_fence(Ordering::SeqCst);
264004e86ffSlogin 
265004e86ffSlogin         volatile_write_bit!(
266004e86ffSlogin             cmdheader.cfl,
267b5b571e0SLoGin             (1 << 5) - 1_u8,
268004e86ffSlogin             (size_of::<FisRegH2D>() / size_of::<u32>()) as u8
269004e86ffSlogin         ); // Command FIS size
270004e86ffSlogin 
271004e86ffSlogin         volatile_set_bit!(cmdheader.cfl, 7 << 5, true); // (p,c,w)都设置为1, Read/Write bit :  Write from device
272004e86ffSlogin         volatile_write!(cmdheader.prdtl, check_length as u16); // PRDT entries count
273004e86ffSlogin 
274004e86ffSlogin         // 设置数据存放地址
275731bc2b3SLoGin         compiler_fence(Ordering::SeqCst);
276004e86ffSlogin         let mut buf_ptr = buf as *const [u8] as *mut usize as usize;
277660a04ceSlogin 
278660a04ceSlogin         // 由于目前的内存管理机制无法把用户空间的内存地址转换为物理地址,所以只能先把数据拷贝到内核空间
279660a04ceSlogin         // TODO:在内存管理重构后,可以直接使用用户空间的内存地址
280b5b571e0SLoGin         let user_buf = verify_area(VirtAddr::new(buf_ptr), buf.len()).is_ok();
281660a04ceSlogin         let mut kbuf = if user_buf {
282b5b571e0SLoGin             let mut x: Vec<u8> = vec![0; buf.len()];
283660a04ceSlogin             x.resize(buf.len(), 0);
284660a04ceSlogin             x.copy_from_slice(buf);
285660a04ceSlogin             Some(x)
286660a04ceSlogin         } else {
287660a04ceSlogin             None
288660a04ceSlogin         };
289660a04ceSlogin 
290660a04ceSlogin         if kbuf.is_some() {
291660a04ceSlogin             buf_ptr = kbuf.as_mut().unwrap().as_mut_ptr() as usize;
292660a04ceSlogin         }
293660a04ceSlogin 
294004e86ffSlogin         #[allow(unused_unsafe)]
295004e86ffSlogin         let cmdtbl = unsafe {
296816ee5aeSLoGin             (MMArch::phys_2_virt(PhysAddr::new(volatile_read!(cmdheader.ctba) as usize))
297816ee5aeSLoGin                 .unwrap()
298816ee5aeSLoGin                 .data() as *mut HbaCmdTable)
299004e86ffSlogin                 .as_mut()
300004e86ffSlogin                 .unwrap()
301004e86ffSlogin         };
302004e86ffSlogin         let mut tmp_count = count;
303731bc2b3SLoGin         compiler_fence(Ordering::SeqCst);
304004e86ffSlogin 
305004e86ffSlogin         unsafe {
306004e86ffSlogin             // 清空整个table的旧数据
307004e86ffSlogin             write_bytes(cmdtbl, 0, 1);
308004e86ffSlogin         }
309004e86ffSlogin 
310004e86ffSlogin         // 8K bytes (16 sectors) per PRDT
311004e86ffSlogin         for i in 0..((volatile_read!(cmdheader.prdtl) - 1) as usize) {
312816ee5aeSLoGin             volatile_write!(
313816ee5aeSLoGin                 cmdtbl.prdt_entry[i].dba,
314816ee5aeSLoGin                 MMArch::virt_2_phys(VirtAddr::new(buf_ptr)).unwrap().data() as u64
315816ee5aeSLoGin             );
316004e86ffSlogin             volatile_write_bit!(cmdtbl.prdt_entry[i].dbc, (1 << 22) - 1, 8 * 1024 - 1); // 数据长度
317004e86ffSlogin             volatile_set_bit!(cmdtbl.prdt_entry[i].dbc, 1 << 31, true); // 允许中断
318004e86ffSlogin             buf_ptr += 8 * 1024;
319004e86ffSlogin             tmp_count -= 16;
320004e86ffSlogin         }
321004e86ffSlogin 
322004e86ffSlogin         // Last entry
323004e86ffSlogin         let las = (volatile_read!(cmdheader.prdtl) - 1) as usize;
324816ee5aeSLoGin         volatile_write!(
325816ee5aeSLoGin             cmdtbl.prdt_entry[las].dba,
326816ee5aeSLoGin             MMArch::virt_2_phys(VirtAddr::new(buf_ptr)).unwrap().data() as u64
327816ee5aeSLoGin         );
328004e86ffSlogin         volatile_set_bit!(cmdtbl.prdt_entry[las].dbc, 1 << 31, true); // 允许中断
329004e86ffSlogin         volatile_write_bit!(
330004e86ffSlogin             cmdtbl.prdt_entry[las].dbc,
331004e86ffSlogin             (1 << 22) - 1,
332004e86ffSlogin             ((tmp_count << 9) - 1) as u32
333004e86ffSlogin         ); // 数据长度
334004e86ffSlogin 
335004e86ffSlogin         // 设置命令
336004e86ffSlogin         let cmdfis = unsafe {
337004e86ffSlogin             ((&mut cmdtbl.cfis) as *mut [u8] as *mut usize as *mut FisRegH2D)
338004e86ffSlogin                 .as_mut()
339004e86ffSlogin                 .unwrap()
340004e86ffSlogin         };
341004e86ffSlogin         volatile_write!(cmdfis.fis_type, FisType::RegH2D as u8);
342004e86ffSlogin         volatile_set_bit!(cmdfis.pm, 1 << 7, true); // command_bit set
343004e86ffSlogin         volatile_write!(cmdfis.command, ATA_CMD_WRITE_DMA_EXT);
344004e86ffSlogin 
345004e86ffSlogin         volatile_write!(cmdfis.lba0, (lba_id_start & 0xFF) as u8);
346004e86ffSlogin         volatile_write!(cmdfis.lba1, ((lba_id_start >> 8) & 0xFF) as u8);
347004e86ffSlogin         volatile_write!(cmdfis.lba2, ((lba_id_start >> 16) & 0xFF) as u8);
348004e86ffSlogin         volatile_write!(cmdfis.lba3, ((lba_id_start >> 24) & 0xFF) as u8);
349004e86ffSlogin         volatile_write!(cmdfis.lba4, ((lba_id_start >> 32) & 0xFF) as u8);
350004e86ffSlogin         volatile_write!(cmdfis.lba5, ((lba_id_start >> 40) & 0xFF) as u8);
351004e86ffSlogin 
352004e86ffSlogin         volatile_write!(cmdfis.countl, (count & 0xFF) as u8);
353004e86ffSlogin         volatile_write!(cmdfis.counth, ((count >> 8) & 0xFF) as u8);
354004e86ffSlogin 
355004e86ffSlogin         volatile_write!(cmdfis.device, 1 << 6); // LBA Mode
356004e86ffSlogin 
357004e86ffSlogin         volatile_set_bit!(port.ci, 1 << slot, true); // Issue command
358004e86ffSlogin 
359004e86ffSlogin         // 等待操作完成
360004e86ffSlogin         loop {
361004e86ffSlogin             if (volatile_read!(port.ci) & (1 << slot)) == 0 {
362004e86ffSlogin                 break;
363004e86ffSlogin             }
364004e86ffSlogin             if (volatile_read!(port.is) & HBA_PxIS_TFES) > 0 {
3652eab6dd7S曾俊                 error!("Write disk error");
366676b8ef6SMork                 return Err(SystemError::EIO);
367004e86ffSlogin             }
368004e86ffSlogin         }
369004e86ffSlogin 
370731bc2b3SLoGin         compiler_fence(Ordering::SeqCst);
371004e86ffSlogin         // successfully read
372004e86ffSlogin         return Ok(count * 512);
373004e86ffSlogin     }
374004e86ffSlogin 
sync(&self) -> Result<(), SystemError>375676b8ef6SMork     fn sync(&self) -> Result<(), SystemError> {
376004e86ffSlogin         // 由于目前没有block cache, 因此sync返回成功即可
377004e86ffSlogin         return Ok(());
378004e86ffSlogin     }
379004e86ffSlogin }
380004e86ffSlogin 
381004e86ffSlogin impl LockedAhciDisk {
new(ctrl_num: u8, port_num: u8) -> Result<Arc<LockedAhciDisk>, SystemError>3829fa0e95eSLoGin     pub fn new(ctrl_num: u8, port_num: u8) -> Result<Arc<LockedAhciDisk>, SystemError> {
3839fa0e95eSLoGin         let devname = scsi_manager().alloc_id().ok_or(SystemError::EBUSY)?;
384004e86ffSlogin         // 构建磁盘结构体
3859fa0e95eSLoGin         let result: Arc<LockedAhciDisk> = Arc::new_cyclic(|self_ref| LockedAhciDisk {
3869fa0e95eSLoGin             blkdev_meta: BlockDevMeta::new(devname),
3879fa0e95eSLoGin             inner: SpinLock::new(AhciDisk {
3889fa0e95eSLoGin                 partitions: Vec::new(),
389004e86ffSlogin                 ctrl_num,
390004e86ffSlogin                 port_num,
391731bc2b3SLoGin                 self_ref: self_ref.clone(),
3929fa0e95eSLoGin             }),
393731bc2b3SLoGin         });
394004e86ffSlogin         let table: MbrDiskPartionTable = result.read_mbr_table()?;
395004e86ffSlogin 
396004e86ffSlogin         // 求出有多少可用分区
397731bc2b3SLoGin         let partitions = table.partitions(Arc::downgrade(&result) as Weak<dyn BlockDevice>);
3989fa0e95eSLoGin         result.inner().partitions = partitions;
3997ae679ddSLoGin 
400004e86ffSlogin         return Ok(result);
401004e86ffSlogin     }
402004e86ffSlogin 
403731bc2b3SLoGin     /// @brief: 从磁盘中读取 MBR 分区表结构体
read_mbr_table(&self) -> Result<MbrDiskPartionTable, SystemError>404676b8ef6SMork     pub fn read_mbr_table(&self) -> Result<MbrDiskPartionTable, SystemError> {
4059fa0e95eSLoGin         let disk = self.inner().self_ref.upgrade().unwrap() as Arc<dyn BlockDevice>;
406731bc2b3SLoGin         MbrDiskPartionTable::from_disk(disk)
407004e86ffSlogin     }
408004e86ffSlogin }
409004e86ffSlogin 
41006d5e247SLoGin impl KObject for LockedAhciDisk {
as_any_ref(&self) -> &dyn core::any::Any41106d5e247SLoGin     fn as_any_ref(&self) -> &dyn core::any::Any {
41206d5e247SLoGin         self
41306d5e247SLoGin     }
41406d5e247SLoGin 
inode(&self) -> Option<Arc<KernFSInode>>41506d5e247SLoGin     fn inode(&self) -> Option<Arc<KernFSInode>> {
41606d5e247SLoGin         todo!()
41706d5e247SLoGin     }
41806d5e247SLoGin 
kobj_type(&self) -> Option<&'static dyn KObjType>41906d5e247SLoGin     fn kobj_type(&self) -> Option<&'static dyn KObjType> {
42006d5e247SLoGin         todo!()
42106d5e247SLoGin     }
42206d5e247SLoGin 
kset(&self) -> Option<Arc<KSet>>42306d5e247SLoGin     fn kset(&self) -> Option<Arc<KSet>> {
42406d5e247SLoGin         todo!()
42506d5e247SLoGin     }
42606d5e247SLoGin 
parent(&self) -> Option<Weak<dyn KObject>>42706d5e247SLoGin     fn parent(&self) -> Option<Weak<dyn KObject>> {
42806d5e247SLoGin         todo!()
42906d5e247SLoGin     }
43006d5e247SLoGin 
set_inode(&self, _inode: Option<Arc<KernFSInode>>)43106d5e247SLoGin     fn set_inode(&self, _inode: Option<Arc<KernFSInode>>) {
43206d5e247SLoGin         todo!()
43306d5e247SLoGin     }
43406d5e247SLoGin 
kobj_state(&self) -> RwLockReadGuard<KObjectState>43506d5e247SLoGin     fn kobj_state(&self) -> RwLockReadGuard<KObjectState> {
43606d5e247SLoGin         todo!()
43706d5e247SLoGin     }
43806d5e247SLoGin 
kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState>43906d5e247SLoGin     fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> {
44006d5e247SLoGin         todo!()
44106d5e247SLoGin     }
44206d5e247SLoGin 
set_kobj_state(&self, _state: KObjectState)44306d5e247SLoGin     fn set_kobj_state(&self, _state: KObjectState) {
44406d5e247SLoGin         todo!()
44506d5e247SLoGin     }
44606d5e247SLoGin 
name(&self) -> alloc::string::String44706d5e247SLoGin     fn name(&self) -> alloc::string::String {
44806d5e247SLoGin         todo!()
44906d5e247SLoGin     }
45006d5e247SLoGin 
set_name(&self, _name: alloc::string::String)45106d5e247SLoGin     fn set_name(&self, _name: alloc::string::String) {
45206d5e247SLoGin         todo!()
45306d5e247SLoGin     }
45406d5e247SLoGin 
set_kset(&self, _kset: Option<Arc<KSet>>)45506d5e247SLoGin     fn set_kset(&self, _kset: Option<Arc<KSet>>) {
45606d5e247SLoGin         todo!()
45706d5e247SLoGin     }
45806d5e247SLoGin 
set_parent(&self, _parent: Option<Weak<dyn KObject>>)45906d5e247SLoGin     fn set_parent(&self, _parent: Option<Weak<dyn KObject>>) {
46006d5e247SLoGin         todo!()
46106d5e247SLoGin     }
462a03c4f9dSLoGin 
set_kobj_type(&self, _ktype: Option<&'static dyn KObjType>)463a03c4f9dSLoGin     fn set_kobj_type(&self, _ktype: Option<&'static dyn KObjType>) {
464a03c4f9dSLoGin         todo!()
465a03c4f9dSLoGin     }
46606d5e247SLoGin }
467b087521eSChiichen 
468b087521eSChiichen impl Device for LockedAhciDisk {
dev_type(&self) -> DeviceType469b087521eSChiichen     fn dev_type(&self) -> DeviceType {
470b087521eSChiichen         return DeviceType::Block;
471b087521eSChiichen     }
472b087521eSChiichen 
id_table(&self) -> IdTable47306d5e247SLoGin     fn id_table(&self) -> IdTable {
474b087521eSChiichen         todo!()
475b087521eSChiichen     }
476b087521eSChiichen 
bus(&self) -> Option<Weak<dyn Bus>>477c566df45SLoGin     fn bus(&self) -> Option<Weak<dyn Bus>> {
47806d5e247SLoGin         todo!("LockedAhciDisk::bus()")
479b087521eSChiichen     }
480b087521eSChiichen 
set_bus(&self, _bus: Option<Weak<dyn Bus>>)481c566df45SLoGin     fn set_bus(&self, _bus: Option<Weak<dyn Bus>>) {
482a03c4f9dSLoGin         todo!("LockedAhciDisk::set_bus()")
483a03c4f9dSLoGin     }
484a03c4f9dSLoGin 
driver(&self) -> Option<Arc<dyn Driver>>48506d5e247SLoGin     fn driver(&self) -> Option<Arc<dyn Driver>> {
48606d5e247SLoGin         todo!("LockedAhciDisk::driver()")
48706d5e247SLoGin     }
48806d5e247SLoGin 
is_dead(&self) -> bool48906d5e247SLoGin     fn is_dead(&self) -> bool {
49006d5e247SLoGin         false
49106d5e247SLoGin     }
49206d5e247SLoGin 
set_driver(&self, _driver: Option<Weak<dyn Driver>>)493a03c4f9dSLoGin     fn set_driver(&self, _driver: Option<Weak<dyn Driver>>) {
49406d5e247SLoGin         todo!("LockedAhciDisk::set_driver()")
495b087521eSChiichen     }
496a03c4f9dSLoGin 
can_match(&self) -> bool497a03c4f9dSLoGin     fn can_match(&self) -> bool {
498a03c4f9dSLoGin         todo!()
499a03c4f9dSLoGin     }
500a03c4f9dSLoGin 
set_can_match(&self, _can_match: bool)501a03c4f9dSLoGin     fn set_can_match(&self, _can_match: bool) {
502a03c4f9dSLoGin         todo!()
503a03c4f9dSLoGin     }
504a03c4f9dSLoGin 
state_synced(&self) -> bool505a03c4f9dSLoGin     fn state_synced(&self) -> bool {
506a03c4f9dSLoGin         todo!()
507a03c4f9dSLoGin     }
50808a2ee40SLoGin 
set_class(&self, _class: Option<Weak<dyn Class>>)5094256da7fSLoGin     fn set_class(&self, _class: Option<Weak<dyn Class>>) {
51008a2ee40SLoGin         todo!()
51108a2ee40SLoGin     }
512*28fe4ad2S黄铭涛 
dev_parent(&self) -> Option<Weak<dyn Device>>513*28fe4ad2S黄铭涛     fn dev_parent(&self) -> Option<Weak<dyn Device>> {
514*28fe4ad2S黄铭涛         None
515*28fe4ad2S黄铭涛     }
516*28fe4ad2S黄铭涛 
set_dev_parent(&self, _dev_parent: Option<Weak<dyn Device>>)517*28fe4ad2S黄铭涛     fn set_dev_parent(&self, _dev_parent: Option<Weak<dyn Device>>) {
518*28fe4ad2S黄铭涛         todo!()
519*28fe4ad2S黄铭涛     }
520b087521eSChiichen }
521b087521eSChiichen 
522004e86ffSlogin impl BlockDevice for LockedAhciDisk {
dev_name(&self) -> &BlockDevName5239fa0e95eSLoGin     fn dev_name(&self) -> &BlockDevName {
5249fa0e95eSLoGin         &self.blkdev_meta.devname
5259fa0e95eSLoGin     }
5269fa0e95eSLoGin 
blkdev_meta(&self) -> &BlockDevMeta5279fa0e95eSLoGin     fn blkdev_meta(&self) -> &BlockDevMeta {
5289fa0e95eSLoGin         &self.blkdev_meta
5299fa0e95eSLoGin     }
5309fa0e95eSLoGin 
disk_range(&self) -> GeneralBlockRange5319fa0e95eSLoGin     fn disk_range(&self) -> GeneralBlockRange {
5329fa0e95eSLoGin         todo!("Get ahci blk disk range")
5339fa0e95eSLoGin     }
5349fa0e95eSLoGin 
535004e86ffSlogin     #[inline]
as_any_ref(&self) -> &dyn core::any::Any536004e86ffSlogin     fn as_any_ref(&self) -> &dyn core::any::Any {
537004e86ffSlogin         self
538004e86ffSlogin     }
539004e86ffSlogin 
540004e86ffSlogin     #[inline]
blk_size_log2(&self) -> u8541004e86ffSlogin     fn blk_size_log2(&self) -> u8 {
542004e86ffSlogin         9
543004e86ffSlogin     }
544004e86ffSlogin 
sync(&self) -> Result<(), SystemError>545676b8ef6SMork     fn sync(&self) -> Result<(), SystemError> {
5469fa0e95eSLoGin         return self.inner().sync();
547004e86ffSlogin     }
548004e86ffSlogin 
549004e86ffSlogin     #[inline]
device(&self) -> Arc<dyn Device>550b087521eSChiichen     fn device(&self) -> Arc<dyn Device> {
5519fa0e95eSLoGin         return self.inner().self_ref.upgrade().unwrap();
552004e86ffSlogin     }
553004e86ffSlogin 
block_size(&self) -> usize554004e86ffSlogin     fn block_size(&self) -> usize {
555004e86ffSlogin         todo!()
556004e86ffSlogin     }
557004e86ffSlogin 
partitions(&self) -> Vec<Arc<Partition>>558004e86ffSlogin     fn partitions(&self) -> Vec<Arc<Partition>> {
5599fa0e95eSLoGin         return self.inner().partitions.clone();
560004e86ffSlogin     }
561b087521eSChiichen 
562b087521eSChiichen     #[inline]
read_at_sync( &self, lba_id_start: BlockId, count: usize, buf: &mut [u8], ) -> Result<usize, SystemError>563eb49bb99S曾俊     fn read_at_sync(
564b087521eSChiichen         &self,
565b087521eSChiichen         lba_id_start: BlockId, // 起始lba编号
566b087521eSChiichen         count: usize,          // 读取lba的数量
567b087521eSChiichen         buf: &mut [u8],
568b087521eSChiichen     ) -> Result<usize, SystemError> {
5699fa0e95eSLoGin         self.inner().read_at(lba_id_start, count, buf)
570b087521eSChiichen     }
571b087521eSChiichen 
572b087521eSChiichen     #[inline]
write_at_sync( &self, lba_id_start: BlockId, count: usize, buf: &[u8], ) -> Result<usize, SystemError>573eb49bb99S曾俊     fn write_at_sync(
574b087521eSChiichen         &self,
575b087521eSChiichen         lba_id_start: BlockId,
576b087521eSChiichen         count: usize,
577b087521eSChiichen         buf: &[u8],
578b087521eSChiichen     ) -> Result<usize, SystemError> {
5799fa0e95eSLoGin         self.inner().write_at(lba_id_start, count, buf)
580b087521eSChiichen     }
581004e86ffSlogin }
582