+// query a single element type from the changer
+fn get_element<F: AsRawFd>(
+ inquiry: &InquiryInfo,
+ sg_raw: &mut SgRaw<F>,
+ element_type: ElementType,
+ allocation_len: u32,
+ mut retry: bool,
+) -> Result<DecodedStatusPage, Error> {
+
+ let mut start_element_address = 0;
+ let number_of_elements: u16 = 1000; // some changers limit the query
+
+ let mut result = DecodedStatusPage {
+ last_element_address: None,
+ transports: Vec::new(),
+ drives: Vec::new(),
+ storage_slots: Vec::new(),
+ import_export_slots: Vec::new(),
+ };
+
+ loop {
+ let cmd = scsi_read_element_status_cdb(start_element_address, number_of_elements, element_type, allocation_len);
+
+ let data = execute_scsi_command(sg_raw, &cmd, "read element status (B8h)", retry)?;
+
+ let page = decode_element_status_page(&inquiry, &data, start_element_address)?;
+
+ retry = false; // only retry the first command
+
+ let returned_number_of_elements = page.transports.len()
+ + page.drives.len()
+ + page.storage_slots.len()
+ + page.import_export_slots.len();
+
+ result.transports.extend(page.transports);
+ result.drives.extend(page.drives);
+ result.storage_slots.extend(page.storage_slots);
+ result.import_export_slots.extend(page.import_export_slots);
+ result.last_element_address = page.last_element_address;
+
+ if let Some(last_element_address) = page.last_element_address {
+ if last_element_address < start_element_address {
+ bail!("got strange element address");
+ }
+ if returned_number_of_elements >= (number_of_elements as usize) {
+ start_element_address = last_element_address + 1;
+ continue; // we possibly have to read additional elements
+ }
+ }
+ break;
+ }
+
+ Ok(result)
+}
+