tape: use loaded media_type in format_media (instead of drive_density)

Required to format LTO4 media loaded in LTO5 drive).

Also contains some SCSI code cleanups.
This commit is contained in:
Dietmar Maurer 2021-04-23 07:27:30 +02:00
parent f2f43e1904
commit 33b8d7e5e8
2 changed files with 34 additions and 13 deletions

View File

@ -106,7 +106,7 @@ pub struct LtoTapeStatus {
pub struct SgTape { pub struct SgTape {
file: File, file: File,
info: InquiryInfo, info: InquiryInfo,
density_code: u8, // drive type max_density_code: u8, // drive type
encryption_key_loaded: bool, encryption_key_loaded: bool,
} }
@ -125,12 +125,12 @@ impl SgTape {
bail!("not a tape device (peripheral_type = {})", info.peripheral_type); bail!("not a tape device (peripheral_type = {})", info.peripheral_type);
} }
let density_code = report_density(&mut file)?; let max_density_code = report_density(&mut file)?;
Ok(Self { Ok(Self {
file, file,
info, info,
density_code, max_density_code,
encryption_key_loaded: false, encryption_key_loaded: false,
}) })
} }
@ -144,6 +144,10 @@ impl SgTape {
&self.info &self.info
} }
pub fn max_density_code(&self) -> u8 {
self.max_density_code
}
pub fn open<P: AsRef<Path>>(path: P) -> Result<SgTape, Error> { pub fn open<P: AsRef<Path>>(path: P) -> Result<SgTape, Error> {
// do not wait for media, use O_NONBLOCK // do not wait for media, use O_NONBLOCK
let file = OpenOptions::new() let file = OpenOptions::new()
@ -198,11 +202,14 @@ impl SgTape {
self.rewind()?; self.rewind()?;
// get info about loaded media first
let (head, _, _) = self.read_compression_page()?;
let mut sg_raw = SgRaw::new(&mut self.file, 16)?; let mut sg_raw = SgRaw::new(&mut self.file, 16)?;
sg_raw.set_timeout(Self::SCSI_TAPE_DEFAULT_TIMEOUT); sg_raw.set_timeout(Self::SCSI_TAPE_DEFAULT_TIMEOUT);
let mut cmd = Vec::new(); let mut cmd = Vec::new();
if self.density_code >= 0x58 { // FORMAT requires LTO5 or newer) if head.medium_type >= 0x58 { // FORMAT requires LTO5 or newer)
cmd.extend(&[0x04, 0, 0, 0, 0, 0]); cmd.extend(&[0x04, 0, 0, 0, 0, 0]);
sg_raw.do_command(&cmd)?; sg_raw.do_command(&cmd)?;
if !fast { if !fast {
@ -210,7 +217,6 @@ impl SgTape {
} }
} else { } else {
// try rewind/erase instead // try rewind/erase instead
self.rewind()?;
self.erase_media(fast)? self.erase_media(fast)?
} }
@ -620,11 +626,7 @@ impl SgTape {
} }
if let Some(buffer_mode) = buffer_mode { if let Some(buffer_mode) = buffer_mode {
let mut mode = head.flags3 & 0b1_000_1111; head.set_buffer_mode(buffer_mode);
if buffer_mode {
mode |= 0b0_001_0000;
}
head.flags3 = mode;
} }
let mut data = Vec::new(); let mut data = Vec::new();
@ -686,8 +688,8 @@ impl SgTape {
Ok(LtoTapeStatus { Ok(LtoTapeStatus {
block_length: block_descriptor.block_length(), block_length: block_descriptor.block_length(),
write_protect: (head.flags3 & 0b1000_0000) != 0, write_protect: head.write_protect(),
buffer_mode: (head.flags3 & 0b0111_0000) >> 4, buffer_mode: head.buffer_mode(),
compression: page.compression_enabled(), compression: page.compression_enabled(),
density_code: block_descriptor.density_code, density_code: block_descriptor.density_code,
}) })

View File

@ -223,12 +223,31 @@ pub struct InquiryInfo {
#[derive(Endian, Debug, Copy, Clone)] #[derive(Endian, Debug, Copy, Clone)]
pub struct ModeParameterHeader { pub struct ModeParameterHeader {
pub mode_data_len: u16, pub mode_data_len: u16,
pub medium_type: u8, pub medium_type: u8, // Note: medium_type amd density_code are not the same
pub flags3: u8, pub flags3: u8,
reserved4: [u8;2], reserved4: [u8;2],
pub block_descriptior_len: u16, pub block_descriptior_len: u16,
} }
impl ModeParameterHeader {
pub fn buffer_mode(&self) -> u8 {
(self.flags3 & 0b0111_0000) >> 4
}
pub fn set_buffer_mode(&mut self, buffer_mode: bool) {
let mut mode = self.flags3 & 0b1_000_1111;
if buffer_mode {
mode |= 0b0_001_0000;
}
self.flags3 = mode;
}
pub fn write_protect(&self) -> bool {
(self.flags3 & 0b1000_0000) != 0
}
}
#[repr(C, packed)] #[repr(C, packed)]
#[derive(Endian, Debug, Copy, Clone)] #[derive(Endian, Debug, Copy, Clone)]
/// SCSI ModeBlockDescriptor for Tape devices /// SCSI ModeBlockDescriptor for Tape devices