(&mut self, base: u64, offset: u64, data: &[u8])
| 5734 | } |
| 5735 | |
| 5736 | fn write(&mut self, base: u64, offset: u64, data: &[u8]) -> Option<Arc<std::sync::Barrier>> { |
| 5737 | match offset { |
| 5738 | B0EJ_FIELD_OFFSET => { |
| 5739 | if data.len() != B0EJ_FIELD_SIZE { |
| 5740 | warn!("Unexpected B0EJ write width: {}", data.len()); |
| 5741 | return None; |
| 5742 | } |
| 5743 | let mut data_array: [u8; 4] = [0, 0, 0, 0]; |
| 5744 | data_array.copy_from_slice(data); |
| 5745 | let mut slot_bitmap = u32::from_le_bytes(data_array); |
| 5746 | |
| 5747 | while slot_bitmap > 0 { |
| 5748 | let slot_id = slot_bitmap.trailing_zeros(); |
| 5749 | if let Err(e) = self.eject_device(self.selected_segment as u16, slot_id as u8) { |
| 5750 | error!("Failed ejecting device {slot_id}: {e:?}"); |
| 5751 | } |
| 5752 | self.cleanup_vfio_ops(); |
| 5753 | slot_bitmap &= !(1 << slot_id); |
| 5754 | } |
| 5755 | } |
| 5756 | PSEG_FIELD_OFFSET => { |
| 5757 | if data.len() != PSEG_FIELD_SIZE { |
| 5758 | warn!("Unexpected PSEG write width: {}", data.len()); |
| 5759 | return None; |
| 5760 | } |
| 5761 | let mut data_array: [u8; 4] = [0, 0, 0, 0]; |
| 5762 | data_array.copy_from_slice(data); |
| 5763 | let selected_segment = u32::from_le_bytes(data_array) as usize; |
| 5764 | if selected_segment >= self.pci_segments.len() { |
| 5765 | error!( |
| 5766 | "Segment selection out of range: {} >= {}", |
| 5767 | selected_segment, |
| 5768 | self.pci_segments.len() |
| 5769 | ); |
| 5770 | return None; |
| 5771 | } |
| 5772 | self.selected_segment = selected_segment; |
| 5773 | } |
| 5774 | _ => error!("Accessing unknown location at base 0x{base:x}, offset 0x{offset:x}"), |
| 5775 | } |
| 5776 | |
| 5777 | debug!("PCI_HP_REG_W: base 0x{base:x}, offset 0x{offset:x}, data {data:?}"); |
| 5778 | |
| 5779 | None |
| 5780 | } |
| 5781 | } |
| 5782 | |
| 5783 | impl Drop for DeviceManager { |
no test coverage detected