Skip to content

Commit c380a7a

Browse files
committed
ide: Handle unsupported IDE commands
1 parent a850d52 commit c380a7a

File tree

1 file changed

+26
-21
lines changed
  • clicky-core/src/devices/generic/ide

1 file changed

+26
-21
lines changed

clicky-core/src/devices/generic/ide/mod.rs

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -429,21 +429,14 @@ impl IdeDrive {
429429
});
430430
}
431431

432-
// TODO?: handle unsupported IDE command according to ATA spec
433-
let cmd = IdeCmd::try_from(cmd).map_err(|_| ContractViolation {
434-
msg: format!("unknown IDE command: {:#04x?}", cmd),
435-
severity: Error, // TODO: this should be Warn, and IDE error bits should be set
436-
stub_val: None,
437-
})?;
438-
439432
(self.reg.status)
440433
.set_bit(reg::STATUS::BSY, true)
441434
.set_bit(reg::STATUS::ERR, false);
442435
self.reg.error = 0;
443436

444437
use IdeCmd::*;
445-
match cmd {
446-
IdentifyDevice => {
438+
match IdeCmd::try_from(cmd) {
439+
Ok(IdentifyDevice) => {
447440
let len = self.blockdev.len();
448441

449442
// fill the iobuf with identification info
@@ -475,7 +468,7 @@ impl IdeDrive {
475468

476469
Ok(())
477470
}
478-
ReadMultiple => {
471+
Ok(ReadMultiple) => {
479472
if self.cfg.multi_sect == 0 {
480473
// TODO?: use the ATA abort mechanism instead of loudly failing
481474
return Err(ContractViolation {
@@ -492,7 +485,7 @@ impl IdeDrive {
492485
self.exec_cmd(ReadSectors as u8)
493486
}
494487
}
495-
ReadDMA | ReadDMANoRetry => {
488+
Ok(ReadDMA) | Ok(ReadDMANoRetry) => {
496489
if !self.cfg.transfer_mode.is_dma() {
497490
// TODO?: use the ATA abort mechanism instead of loudly failing
498491
return Err(ContractViolation {
@@ -508,7 +501,7 @@ impl IdeDrive {
508501
(self.reg.status).set_bit(reg::STATUS::BSY, false);
509502
self.exec_cmd(ReadSectors as u8)
510503
}
511-
ReadSectors | ReadSectorsNoRetry => {
504+
Ok(ReadSectors) | Ok(ReadSectorsNoRetry) => {
512505
let offset = match self.get_sector_offset() {
513506
Some(offset) => offset,
514507
None => {
@@ -554,14 +547,14 @@ impl IdeDrive {
554547

555548
Ok(())
556549
}
557-
StandbyImmediate | StandbyImmediateAlt => {
550+
Ok(StandbyImmediate) | Ok(StandbyImmediateAlt) => {
558551
// I mean, it's a virtual disk, there is no "spin up / spin down"
559552
self.reg.status.set_bit(reg::STATUS::BSY, false);
560553

561554
// TODO: fire interrupt
562555
Ok(())
563556
}
564-
WriteMultiple => {
557+
Ok(WriteMultiple) => {
565558
if self.cfg.multi_sect == 0 {
566559
// TODO?: use the ATA abort mechanism instead of loudly failing
567560
return Err(ContractViolation {
@@ -579,7 +572,7 @@ impl IdeDrive {
579572
self.exec_cmd(WriteSectors as u8)
580573
}
581574
}
582-
WriteDMA | WriteDMANoRetry => {
575+
Ok(WriteDMA) | Ok(WriteDMANoRetry) => {
583576
if !self.cfg.transfer_mode.is_dma() {
584577
// TODO?: use the ATA abort mechanism instead of loudly failing
585578
return Err(ContractViolation {
@@ -595,7 +588,7 @@ impl IdeDrive {
595588
(self.reg.status).set_bit(reg::STATUS::BSY, false);
596589
self.exec_cmd(WriteSectors as u8)
597590
}
598-
WriteSectors | WriteSectorsNoRetry => {
591+
Ok(WriteSectors) | Ok(WriteSectorsNoRetry) => {
599592
// NOTE: this code is somewhat UNTESTED
600593

601594
let offset = match self.get_sector_offset() {
@@ -636,7 +629,7 @@ impl IdeDrive {
636629
Ok(())
637630
}
638631

639-
SetMultipleMode => {
632+
Ok(SetMultipleMode) => {
640633
self.cfg.multi_sect = self.reg.sector_count;
641634

642635
// TODO: implement proper multi-sector support
@@ -650,7 +643,7 @@ impl IdeDrive {
650643
Ok(())
651644
}
652645

653-
SetFeatures => {
646+
Ok(SetFeatures) => {
654647
match self.reg.feature {
655648
// Enable 8-bit data transfers
656649
0x01 => self.cfg.eightbit = true,
@@ -671,7 +664,7 @@ impl IdeDrive {
671664
Ok(())
672665
}
673666

674-
FlushCache => {
667+
Ok(FlushCache) => {
675668
// uhh, we don't implement caching
676669
(self.reg.status)
677670
.set_bit(reg::STATUS::BSY, false)
@@ -681,7 +674,7 @@ impl IdeDrive {
681674
Ok(())
682675
}
683676

684-
Sleep | SleepAlt => {
677+
Ok(Sleep) | Ok(SleepAlt) => {
685678
// uhh, it's an emulated drive.
686679
// just assert the irq and go on our merry way
687680
(self.reg.status).set_bit(reg::STATUS::BSY, false);
@@ -690,11 +683,23 @@ impl IdeDrive {
690683
Ok(())
691684
}
692685

693-
InitializeDriveParameters => {
686+
Ok(InitializeDriveParameters) => {
694687
(self.reg.status).set_bit(reg::STATUS::BSY, false);
695688
self.irq.assert();
696689
Ok(())
697690
}
691+
692+
Err(_) => {
693+
(self.reg.status)
694+
.set_bit(reg::STATUS::BSY, false)
695+
.set_bit(reg::STATUS::ERR, true);
696+
self.reg.error = 1;
697+
Err(ContractViolation {
698+
msg: format!("unknown IDE command: {:#04x?}", cmd),
699+
severity: Warn,
700+
stub_val: None,
701+
})
702+
}
698703
}
699704
}
700705
}

0 commit comments

Comments
 (0)