command.rs 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. use super::bindings::EINVAL;
  2. use crate::kernel::mem::paging::Page;
  3. use crate::prelude::*;
  4. pub trait Command {
  5. fn pages(&self) -> &[Page];
  6. fn lba(&self) -> u64;
  7. // in sectors
  8. fn count(&self) -> u16;
  9. fn cmd(&self) -> u8;
  10. fn write(&self) -> bool;
  11. }
  12. pub struct IdentifyCommand {
  13. page: Page,
  14. }
  15. impl IdentifyCommand {
  16. pub fn new() -> Self {
  17. Self {
  18. page: Page::alloc(),
  19. }
  20. }
  21. }
  22. impl Command for IdentifyCommand {
  23. fn pages(&self) -> &[Page] {
  24. core::slice::from_ref(&self.page)
  25. }
  26. fn lba(&self) -> u64 {
  27. 0
  28. }
  29. fn count(&self) -> u16 {
  30. 1
  31. }
  32. fn cmd(&self) -> u8 {
  33. 0xEC
  34. }
  35. fn write(&self) -> bool {
  36. false
  37. }
  38. }
  39. pub struct ReadLBACommand<'lt> {
  40. pages: &'lt [Page],
  41. lba: u64,
  42. count: u16,
  43. }
  44. impl<'lt> ReadLBACommand<'lt> {
  45. pub fn new(pages: &'lt [Page], lba: u64, count: u16) -> KResult<Self> {
  46. if pages.len() > 248 {
  47. return Err(EINVAL);
  48. }
  49. let buffer_tot_len = pages.iter().fold(0, |acc, page| acc + page.len());
  50. if buffer_tot_len < count as usize * 512 {
  51. return Err(EINVAL);
  52. }
  53. Ok(Self { pages, lba, count })
  54. }
  55. }
  56. impl Command for ReadLBACommand<'_> {
  57. fn pages(&self) -> &[Page] {
  58. self.pages
  59. }
  60. fn lba(&self) -> u64 {
  61. self.lba
  62. }
  63. fn count(&self) -> u16 {
  64. self.count
  65. }
  66. fn cmd(&self) -> u8 {
  67. 0xC8
  68. }
  69. fn write(&self) -> bool {
  70. false
  71. }
  72. }