- Split AacsError { detail } into 13 specific error variants (AacsCertShort,
AacsAgidAlloc, AacsCertRejected, etc.) with unique error codes E7001-E7012
- Split DiscError { detail } into 7 specific variants (DiscRead, MplsParse,
ClpiParse, UdfNotFound, DiscNoTitles, DiscTitleRange, DiscNoExtents)
- Add WriteError (E5001), KeydbLoad (E8005), MuxLookahead (E9000), MuxWrite (E9001)
- Add OpenDisc API for single-call open+scan+rip workflow
- Remove all English text from error Display impl (code-only output)
- Normalize doc comments to use -- instead of em dash for ASCII consistency
39 lines
1.3 KiB
Rust
39 lines
1.3 KiB
Rust
//! MT1959 variant A firmware upload.
|
||
//!
|
||
//! WRITE_BUFFER (0x3B) → verify READ_BUFFER (0x45) → unlock × 2
|
||
|
||
use crate::error::Result;
|
||
use crate::scsi::{DataDirection, ScsiTransport};
|
||
use super::Mt1959;
|
||
|
||
const SCSI_WRITE_BUFFER: u8 = 0x3B;
|
||
const VERIFY_BUFFER_ID: u8 = 0x45;
|
||
|
||
pub(super) fn load_firmware(mt: &mut Mt1959, scsi: &mut dyn ScsiTransport) -> Result<()> {
|
||
let firmware = &mt.profile.firmware;
|
||
if firmware.is_empty() {
|
||
return Err(crate::error::Error::UnlockFailed);
|
||
}
|
||
|
||
// Upload firmware via WRITE_BUFFER
|
||
let len = firmware.len();
|
||
let cdb = [
|
||
SCSI_WRITE_BUFFER, 0x06, 0x00,
|
||
0x00, 0x00, 0x00,
|
||
(len >> 16) as u8, (len >> 8) as u8, len as u8,
|
||
0x00,
|
||
];
|
||
let mut data = firmware.clone();
|
||
scsi.execute(&cdb, DataDirection::ToDevice, &mut data, 30_000)?;
|
||
|
||
// Verify firmware loaded (non-fatal — different buffer_id 0x45)
|
||
let verify_cdb = [super::SCSI_READ_BUFFER, super::MODE_A, VERIFY_BUFFER_ID, 0x00, 0x00, 0x00, 0x00, 0x00, super::VALIDATE_RESPONSE_SIZE, 0x00];
|
||
let mut verify_resp = [0u8; super::VALIDATE_RESPONSE_SIZE as usize];
|
||
let _ = scsi.execute(&verify_cdb, DataDirection::FromDevice, &mut verify_resp, 5_000);
|
||
|
||
// Double unlock after firmware upload
|
||
mt.do_unlock(scsi)?;
|
||
mt.do_unlock(scsi)?;
|
||
Ok(())
|
||
}
|